当前位置:   article > 正文

C语言实现数据结构:二叉树_以二叉链表创建二叉树 输出二叉树的中序结果的算法步骤

以二叉链表创建二叉树 输出二叉树的中序结果的算法步骤

第二次上机实验报告

作业题目1:

实现以下算法:

1.以二叉链表表示二叉树,根据输入建立一棵二叉树;

2.输出二叉树的先序遍历结果;

3.输出二叉树的中序遍历结果;

4.出二叉树的后序遍历结果。

程序运行结果截图,需测试各种情况。写出测试过程中遇到的主要问题及所采用的解决措施。

运行结果截图:

 

主要问题:创建树和输入树时顺序不好控制

解决办法:按树形输入,如果没有数据则输入-1,来提示输入已经结束了

代码:

BiTree.h

  1. #pragma once
  2. #include"function.h"
  3. typedef struct Tree {
  4. int data; // 数据域
  5. struct Tree* lchild; // 左子树指针
  6. struct Tree* rchild; // 右子树指针
  7. }Tree, * BiTree;
  8. BiTree CreateBiTree();
  9. void PreOrderTraverse(BiTree T);
  10. void InOrderTraverse(BiTree T);
  11. void PostOrderTraverse(BiTree T);

function.h

  1. #pragma once
  2. #include<stdio.h>
  3. #include<stdlib.h>

function.cpp

  1. #include"BiTree.h"
  2. BiTree CreateBiTree()
  3. {
  4. int data;
  5. int temp;
  6. BiTree T;
  7. scanf("%d", &data);
  8. temp = getchar(); // 必须吸收一个后面的空格
  9. if (data == -1) { // 输入-1 代表此节点下子树不存数据,不继续递归创建
  10. return NULL;
  11. }
  12. else {
  13. T = (BiTree)malloc(sizeof(Tree));
  14. T->data = data; //把当前输入的数据存入当前节点指针的数据域中
  15. printf("请输入%d的左子树:(若无数据则输入-1)\n", data);
  16. T->lchild = CreateBiTree(); //递归创建左子树
  17. printf("请输入%d的右子树:(若无数据则输入-1)\n", data);
  18. T->rchild = CreateBiTree(); //开始到上一级节点的右边递归创建左右子树
  19. return T; //返回根节点
  20. }
  21. }
  22. void PreOrderTraverse(BiTree T) //先序遍历二叉树
  23. {
  24. if (T == NULL)
  25. {
  26. return;
  27. }
  28. printf("%d ", T->data);
  29. PreOrderTraverse(T->lchild);
  30. PreOrderTraverse(T->rchild);
  31. }
  32. void InOrderTraverse(BiTree T) //中序遍历二叉树
  33. {
  34. if (T == NULL)
  35. {
  36. return;
  37. }
  38. InOrderTraverse(T->lchild);
  39. printf("%d ", T->data);
  40. InOrderTraverse(T->rchild);
  41. }
  42. // 后序遍历
  43. void PostOrderTraverse(BiTree T) //后序遍历二叉树
  44. {
  45. if (T == NULL)
  46. {
  47. return;
  48. }
  49. PostOrderTraverse(T->lchild);
  50. PostOrderTraverse(T->rchild);
  51. printf("%d ", T->data);
  52. }

main.cpp

  1. #include"BiTree.h"
  2. int main()
  3. {
  4. BiTree S;
  5. printf("请输入根结点数据:\n");
  6. S = CreateBiTree();
  7. printf("先序遍历结果: \n");
  8. PreOrderTraverse(S);
  9. printf("\n中序遍历结果: \n");
  10. InOrderTraverse(S);
  11. printf("\n后序遍历结果: \n");
  12. PostOrderTraverse(S);
  13. return 0;
  14. }

作业题目2:求二叉树第k层结点的个数

求二叉树第k层结点的个数。

程序运行结果截图,需测试各种情况。写出测试过程中遇到的主要问题及所采用的解决措施。

运行结果截图:

主要问题:输入树和查找层数的顺序易错

解决办法:先输入非空结点的个数,这样有助于树的建立

代码:

BiTree.h

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. using namespace std;
  5. int sum = 0;
  6. int K, L;
  7. typedef struct binode
  8. {
  9. int data;
  10. struct binode* lchild, * rchild;
  11. }Binode, * Bitree;
  12. void btinsert(Bitree& T, int i, int j, int d);
  13. void traversal(Bitree T, int l);

main.cpp

  1. #include"BiTree.h"
  2. int main()
  3. {
  4. Bitree h = NULL;
  5. printf("二叉树中非空结点的个数:\n");
  6. scanf("%d", &K);
  7. printf("要查找的层数k:\n");
  8. scanf("%d", &L);
  9. printf("按照顺序输入二叉树的多个结点值 (包含空结点,结点值之间用空格隔开):\n");
  10. for (int i = 1; K > 0; i++)
  11. {
  12. int d;
  13. scanf("%d", &d);
  14. if (d) K--;
  15. btinsert(h, i, 1, d);
  16. }
  17. traversal(h, 1);
  18. printf("二叉树第k层的结点个数为:%d\n", sum);
  19. return 0;
  20. }
  21. void btinsert(Bitree& T, int i, int j, int d)
  22. {
  23. if (!d) return;
  24. if (i == j)
  25. {
  26. T = (Bitree)malloc(sizeof(Binode));
  27. T->data = d;
  28. T->lchild = T->rchild = NULL;
  29. }
  30. else
  31. {
  32. int t = i;
  33. while (t != j * 2 && t != j * 2 + 1)
  34. {
  35. t /= 2;
  36. }
  37. if (t == j * 2)
  38. {
  39. btinsert(T->lchild, i, j * 2, d);
  40. }
  41. else
  42. {
  43. btinsert(T->rchild, i, j * 2 + 1, d);
  44. }
  45. }
  46. }
  47. void traversal(Bitree T, int l)
  48. {
  49. if (T == NULL) return;
  50. if (l == L) sum++;
  51. traversal(T->lchild, l + 1);
  52. traversal(T->rchild, l + 1);
  53. }

作业题目3:

1.题目描述:

利用二叉树计算表达式的值。建立表达式树,并计算表达式的值。

2.问题分析:

1.程序的功能要求;

利用二叉树这一数据结构,建立树并且计算表达式求值

2.程序的界面设计:

第一行显示:“请输入表达式:”,然后自行输入表达式

第二行显示:“你输入的表达式为:……”

第三行显示:“Your result is ……”,显示计算结果

3.程序的错误处理:当输入非法数据时,直接结束程序

1.数据类型设计:

typedef struct  TNode {

 int flag;

 int data;//flag=0

 char ch;//flag=1

 struct TNode* lChild;//左孩子

 struct  TNode* rChild;//右孩子

};

2.算法设计(算法的基本思想、具体步骤,各程序模块之间的层次(调用)关系流程图等):

在输入时,先把输入的结果存在一个数组中,然后用二叉树保存;遍历树,当发现为+、—、*、/四种符号时,则让树的左孩子、右孩子进行相应的操作,并把结果返回上一级字树的根。递归实现以上步骤,最终返回的根数据则为表达式的值。

3.测试分析

设计测试范例(测试数据包括正确的输入、边界条件、含有错误的输入等),列出程序的测试结果(附截图),测试结果的分析与讨论。可列出测试过程中遇到的主要问题及所采用的解决措施。

 4.心得

对实验设计与实现过程的回顾和分析,说明程序的改进思想、经验和体会。

对树这种类型的数据结构,一般尽量使用递归定义,这样可以简化运算,使其更高效。

在进行更大型的程序设计时,一般混用多个数据结构,比如栈、队列等,但要注意防止混淆。

5.附录

列出程序文件清单,及文件功能。

头文件:

count.h:存放头文件、基本数据结构、函数声明

源文件:

main.cpp:存放主函数和其他函数的文件

代码注释要求:

  1. 对关键的算法实现代码有必要的注释
  2. 函数说明格式:

*****************************************************

函数名:

函数功能:

输入参数:

       类型,参数名,含义

输出参数:

       返回值,含义

文件提交要求:

将两道题目各自的完整工程(包含该工程下所有目录和文件)和此文档一起打包,以组内学生姓名作为文件名,上传提交。例如Stu1_Stu2.zip

代码:

count.h

  1. #pragma once
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdlib.h>
  5. #include <ctype.h>
  6. #define MAX 0x3f3f3f3f
  7. /* run this program using the console pauser or add your own getch, system("pause") or input loop */
  8. typedef struct TNode {
  9. int flag;
  10. int data;//flag=0
  11. char ch;//flag=1
  12. struct TNode* lChild;//左孩子
  13. struct TNode* rChild;//右孩子
  14. };
  15. //(5+3*4)*2/3-2*5
  16. int cal(struct TNode* root);
  17. int check(char s[], int start, int end);
  18. void postOrder(struct TNode* root);
  19. struct TNode* buildTree(char s[], int start, int end);

main.cpp

  1. #include"count.h"
  2. int main(int argc, char** argv) {
  3. while (1) {
  4. char a[200];
  5. printf("请输入表达式:");
  6. scanf("%s", a);
  7. printf("你输入的表达式为:%s\n", a);
  8. struct TNode* b = (struct TNode*)malloc(sizeof(struct TNode));
  9. b = buildTree(a, 0, strlen(a) - 1);
  10. printf("Your result is %d\n", cal(b));
  11. }
  12. return 0;
  13. }
  14. int cal(struct TNode* root) {
  15. if (root->flag == 1) {
  16. switch (root->ch) {
  17. case '+': {
  18. return cal(root->lChild) + cal(root->rChild);
  19. break;
  20. }
  21. case '-': {
  22. return cal(root->lChild) - cal(root->rChild);
  23. break;
  24. }
  25. case '/': {
  26. return cal(root->lChild) / cal(root->rChild);
  27. break;
  28. }
  29. case '*': {
  30. return cal(root->lChild) * cal(root->rChild);
  31. break;
  32. }
  33. }
  34. }
  35. return root->data;
  36. }
  37. int check(char s[], int start, int end) {
  38. int i;
  39. int sum = 0;
  40. int flag = 1;
  41. if (s[start] == '-') {
  42. flag = -1;
  43. start++;
  44. }
  45. for (i = start; i <= end; i++) {
  46. if (!isdigit(s[i])) return MAX;
  47. sum = sum * 10 + s[i] - '0';
  48. }
  49. return sum * flag;
  50. }
  51. void postOrder(struct TNode* root) {
  52. if (root) {
  53. postOrder(root->lChild);
  54. postOrder(root->rChild);
  55. if (root->flag == 0) {
  56. printf("%d ", root->data);
  57. }
  58. else {
  59. printf("%c ", root->ch);
  60. }
  61. }
  62. }
  63. struct TNode* buildTree(char s[], int start, int end) {
  64. struct TNode* root = (struct TNode*)malloc(sizeof(struct TNode));
  65. int cnt = 0;
  66. int m;
  67. int i;
  68. if (start > end) return NULL;
  69. int posPlusOrSub = 0;//加减号位置
  70. int numPlusOrSub = 0;//加减号个数
  71. int posDivOrMul = 0;//乘除号位置
  72. int numDivOrMul = 0;//乘除号个数
  73. int num;
  74. num = check(s, start, end);
  75. if (num != 0x3f3f3f3f) {//只有数字
  76. root->flag = 0;
  77. root->data = num;
  78. root->lChild = NULL;
  79. root->rChild = NULL;
  80. return root;
  81. }
  82. //有操作符
  83. int in_brackets = 0;//不在括号里的标识符
  84. for (int k = start; k <= end; k++) {
  85. if (s[k] == '(') {
  86. in_brackets++;
  87. }
  88. else if (s[k] == ')') {
  89. in_brackets--;
  90. }
  91. if (!in_brackets) {//括号之外
  92. if (s[k] == '+' || s[k] == '-') {
  93. posPlusOrSub = k;
  94. numPlusOrSub++;
  95. }
  96. else if (s[k] == '*' || s[k] == '/') {
  97. posDivOrMul = k;//乘除号位置
  98. numDivOrMul++;//乘除号个数
  99. }
  100. }
  101. }
  102. int pos_root;
  103. //寻找根节点 有加减用加减没加减用乘除
  104. if (numPlusOrSub) {
  105. pos_root = posPlusOrSub;
  106. }
  107. else if (numDivOrMul) {
  108. pos_root = posDivOrMul;
  109. }
  110. else {//找不到根 递归再找一次
  111. return buildTree(s, start + 1, end - 1);
  112. }
  113. root->flag = 1;
  114. root->ch = s[pos_root];
  115. root->lChild = buildTree(s, start, pos_root - 1);
  116. root->rChild = buildTree(s, pos_root + 1, end);
  117. return root;
  118. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/233182
推荐阅读
相关标签
  

闽ICP备14008679号