1、数据结构课程设计报告二叉树的生成和遍历专 业 信息管理与信息系统 班 级 110514 小组成员 110514128 汤文莹110514129 王玉珏 110514130 张蓓蕾 110514131 张慕琦 课程设计:二叉树的生成和遍历一、 任务描述1. 将二叉树以广义表形式存储在一个 TXT 文件上,通过读取 TXT 文件,建立二叉树; 2. 求树的高度 3. 实现二叉树的前序、中序和后序遍历; 4. 将输出结果存储在文件内。二、问题分析1.设计思想以广义表格式输入一个二叉树,将其接收至一维数组中,利用栈结构建立二叉链表树;通过先、中、后访问根结点递归算法遍历二叉树;利用队列的入队、出队操作
2、实现二叉树的层次遍历。例如:a(c(,d),f(g,)建立如下图所示二叉树。cadfg2.数据结构定义队列数组长度# define QueueMaxSize 20定义栈数组长度# define StackMaxSize 10定义二叉树数据类型typedef char ElemType;struct BTreeNodeElemType data;struct BTreeNode * left;struct BTreeNode * right;BTreeNode;3.主要模块设计初始化二叉树void InitBTree(struct BTreeNode* BT)根据 a 所定义的二叉树广义表字符串
3、建立对应的存储结构void CreateBTree(struct BTreeNode * BT,char * a) 前序遍历二叉树void Preorder(struct BTreeNode * BT)if(BT!=NULL) printf(“%c“,BT-data); /*访问根结点*/Preorder(BT-left); /*前序遍历左子树*/Preorder(BT-right); /*前序遍历右子树*/中序遍历二叉树void Inorder(struct BTreeNode * BT)if(BT!=NULL) Inorder(BT-left); /*中序遍历左子树*/printf(“%c
4、“,BT-data); /*访问根结点*/Inorder(BT-right); /*中序遍历右子树*/后序遍历二叉树void Postorder(struct BTreeNode * BT)if(BT!=NULL) Postorder(BT-left); /*后序遍历左子树*/Postorder(BT-right); /*后序遍历右子树*/printf(“%c“,BT-data); /*访问根结点*/由指针指向的一颗二叉树的深度int BTreeDepth(struct BTreeNode * BT)按层遍历由 BT 指针所指向的二叉树void Levelorder(struct BTreeN
5、ode * BT主菜单先序遍历后序遍历广度优先遍历结束将以广义表形式输入的二叉树接收到数组 str80中,成功建立二叉树4.详细设计1)二叉树的建立其中 mark 的值 1、2、3 、 4 分别指 stri为字母、 (、 , 、 );tag 为左、右孩子的标志;二叉树深度中序遍历root=null检查 str10(), mark=1;root-data=str0,root-lchild=root-rchild=null;p=root;str0是否为字母 YNNmark=2?mark=2stri入栈tag=0mark=3?mark=3tag=1Nmark=4pop 为空return nullNY
6、Y)mark=1struct BTreeNodeElemType data;struct BTreeNode * left;struct BTreeNode * right;BTreeNode;void InitBTree(struct BTreeNode* BT)/*初始化二叉树,即把树根指针置空*/*BT=NULL;void CreateBTree(struct BTreeNode * BT,char * a) /*根据 a 所定义的二叉树广义表字符串建立对应的存储结构*/struct BTreeNode * p;/*定义 s 数组作为存储根结点指针的栈使用*/struct BTreeNo
7、de * sStackMaxSize;/*定义 top 作为 s 栈的栈顶指针,初值为-1,表示空栈*/int top=-1;/*用 k 作为处理结点的左子树和右子树的标记,k=1 处理左子树,k=2 处理右子树*/int k;/*用 i 扫描数组 a 中存储的二叉树广义表字符串,初值为 0*/int i=0;/*把树根指针置为空,即从空树开始建立二叉树*/*BT=NULL;/*每循环一次处理一个字符,直到扫描到字符串结束0 为止*/while (ai)switch(ai)case : /*对空格不做任何处理*/break;case (:if(top=StackMaxSize-1)printf
8、(“栈空间太小,需增加 StackMaxSize!n“);exit(1);top+;stop=p;k=1;break;case ):if(top=-1)printf(“二叉树广义表字符串错!n“);exit(1);top-;break;case ,:k=2;break;default:p=(struct BTreeNode * )malloc(sizeof(struct BTreeNode);p-data=ai;p-left=p-right=NULL;if(*BT=NULL)*BT=p;elseif(k=1)stop-left=p;elsestop-right=p; /*switch end*
9、/*为扫描下一个字符串修改 i 值*/i+;void PrintBTree(struct BTreeNode * BT)/*输出二叉数的广义表表示*/*数为空时自然结束递归,否则执行如下操作*/if(BT=NULL) /*输出根结点的值*/printf(“%c“,BT-data);/*输出左、右子树*/if(BT-left!=NULL | BT-right!=NULL)printf(“(“); /*输出左括号*/PrintBTree(BT-left); /*输出左子树*/if(BT-right!=NULL) PrintBTree(BT-right); /*输出右子树*/printf(“)“);
10、 /*输出右括号*/void Preorder(struct BTreeNode * BT)if(BT!=NULL) printf(“%c“,BT-data); /*访问根结点*/Preorder(BT-left); /*前序遍历左子树*/Preorder(BT-right); /*前序遍历右子树*/void Inorder(struct BTreeNode * BT)if(BT!=NULL) Inorder(BT-left); /*中序遍历左子树*/printf(“%c“,BT-data); /*访问根结点*/Inorder(BT-right); /*中序遍历右子树*/void Postor
11、der(struct BTreeNode * BT)if(BT!=NULL) Postorder(BT-left); /*后序遍历左子树*/Postorder(BT-right); /*后序遍历右子树*/printf(“%c“,BT-data); /*访问根结点*/void Levelorder(struct BTreeNode * BT) /*按层遍历由 BT 指针所指向的二叉树*/struct BTreeNode * p;/*定义队列所使用的数组空间,元素类型为指向结点的指针类型*/struct BTreeNode* qQueueMaxSize;/*定义队首指针和队尾指针,初始均置 0 表
12、示空队*/int front=0,rear=0;/*将树根指针进队*/if(BT!=NULL) rear=(rear+1)% QueueMaxSize;qrear=BT;/*当队列非空时执行循环*/while(front!=rear) /*使队首指针指向队首元素*/front=(front+1)% QueueMaxSize;/*删除队首元素,输出队首元素所指结点的值*/p=qfront;printf(“%c“,p-data);/*若结点存在左孩子,则左孩子指针结点进队*/if(p-left!=NULL)rear=(rear+1)% QueueMaxSize;qrear=p-left;/*若结点
13、存在右孩子,则右孩子指针结点进队*/if(p-right!=NULL)rear=(rear+1)% QueueMaxSize;qrear=p-right;int BTreeDepth(struct BTreeNode * BT) /*求由指针指向的一颗二叉树的深度*/if(BT=NULL)return 0; /*对于空树,返回 0 并结束递归*/else /*计算左子树的深度*/int dep1=BTreeDepth(BT-left);/*计算右子树的深度*/int dep2=BTreeDepth(BT-right);/*返回树的深度*/if(dep1dep2)return dep1+1;el
14、sereturn dep2+1;void menu()/窗体显示菜单printf(“n=请在下列序号中选择一个并输入:n“);printf(“ (1)-重新输入二叉树 n“);printf(“ (2)-前序遍历二叉树 n“);printf(“ (3)-中序遍历二叉树 n“);printf(“ (4)-后序遍历二叉树 n“);printf(“ (5)-广度优先遍历二叉树 n“);printf(“ (6)-显示二叉树深度 n“);printf(“ (0)-退出 n“);void Wrong()/错误提示printf(“n=按键错误!n“);getchar();/保留错误信息的显示void main
15、()/*定义指向二叉树节点的操作,并用指针作为树根指针*/struct BTreeNode * bt;/*定义一个用于存放二叉树广义表的字符数组*/char b50;/*定义 ElemType 类型的对象 X 和指针对象 px*/ElemType x,* px;/*初始化二叉树,即置树根 bt 为空*/InitBTree(/*从键盘向字符数组 b 输入二叉树广义表标识的字符串*/printf(“输入二叉树广义表字符串:n“);printf(“输入格式为:a(c(m,d(s,z),e(t(h,k),b(i)n“);scanf(“%s“,b);/*建立以 bt 作为树根指针的二叉树的链接存储结构*
16、/CreateBTree(menu();while(10)/界面的显示实现int p;scanf(“%d“, switch(p)case 0:printf(“=谢谢使用!n“);getchar();break;case 1:printf(“请重新输入二叉树广义表字符串:n“);printf(“输入格式为:a(c(m,d(s,z),e(t(h,k),b(i)n“);scanf(“%s“,b);/*建立以 bt 作为树根指针的二叉树的链接存储结构*/CreateBTree(printf(“n“);getchar();break;case 2:/*以广义表形式输入二叉树*/PrintBTree(bt
17、);printf(“n“);/*前序遍历以 bt 为树根指针的二叉树*/printf(“前序: “);Preorder(bt); printf(“n“);getchar();break;case 3:/*以广义表形式输入二叉树*/PrintBTree(bt);printf(“n“);/*中序遍历以 bt 为树根指针的二叉树*/printf(“中序: “);Inorder(bt); printf(“n“);getchar();break;case 4:/*以广义表形式输入二叉树*/PrintBTree(bt);printf(“n“);/*后序遍历以 bt 为树根指针的二叉树*/printf(“后
18、序: “);Postorder(bt); printf(“n“);getchar();break;case 5:/*以广义表形式输入二叉树*/PrintBTree(bt);printf(“n“);/*接层遍历以 bt 为树根指针的二叉树*/printf(“广度优先: “);Levelorder(bt); printf(“n“);getchar();break;case 6:/*以广义表形式输入二叉树*/PrintBTree(bt);printf(“n“);/*求出以 bt 为树根指针的二叉树的深度*/printf(“二叉树的深度: “);printf(“%dn“,BTreeDepth(bt);
19、getchar();break;default:Wrong();printf(“n 请按任意键继续.“);getchar();break;3、运行结果四、设计总结二叉树是数据结构的的基本内容。虽然程序规模不大,经过查找资料,参考网上以及课本上的实例,仍免不了各种错误的出现。编程过程需要很大的毅力和耐心,而且要有良好的思维和扎实的专业基础知识,所以我们需要不断的学习,发现自身不足之处并改正它,逐步提高自己。程序设计让我们懂了许课程设计究竟是什么意思了,要用我们的双手编写出一个个程序来为他人带来方便。其中也遇到了现实中的一些问题,比如说,数据量很的问题,这在程序的各种算法上提出了很严的要求,数据量大就需要的时间就多,相应的效率问题也很重要。在银行、通信、军事上如果一个程序在运算大量数据上能提高一点效率那么它就能节省许多的时间和金钱。这也就是一个创造吧。在以后的程序设计中都应该好好思考这个问题。有一高效率才是最好程序。