课程设计二叉树

合集下载

数据结构c语言课设-二叉树排序

数据结构c语言课设-二叉树排序

题目:二叉排序树的实现1 内容和要求1)编程实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进展先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

4)分别用二叉排序树和数组去存储一个班(50 人以上)的成员信息(至少包括学号、姓名、成绩3 项),比照查找效率,并说明在什么情况下二叉排序树效率高,为什么?2 解决方案和关键代码2.1 解决方案:先实现二叉排序树的生成、插入、删除,编写DisplayBST函数把遍历结果用树的形状表示出来。

前中后根遍历需要用到栈的数据构造,分模块编写栈与遍历代码。

要求比照二叉排序树和数组的查找效率,首先建立一个数组存储一个班的成员信息,分别用二叉树和数组查找,利用clock〔〕函数记录查找时间来比照查找效率。

2.2关键代码树的根本构造定义及根本函数typedef struct{KeyType key;} ElemType;typedef struct BiTNode//定义链表{ElemType data;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree, *SElemType;//销毁树int DestroyBiTree(BiTree &T){if (T != NULL)free(T);return 0;}//清空树int ClearBiTree(BiTree &T){if (T != NULL){T->lchild = NULL;T->rchild = NULL;T = NULL;}return 0;}//查找关键字,指针p返回int SearchBST(BiTree T, KeyType key, BiTree f, BiTree &p) {if (!T){p = f;return FALSE;}else if EQ(key, T->data.key){p = T;return TRUE;}else if LT(key, T->data.key)return SearchBST(T->lchild, key, T, p);elsereturn SearchBST(T->rchild, key, T, p);}二叉树的生成、插入,删除生成void CreateBST(BiTree &BT, BiTree p){int i;ElemType k;printf("请输入元素值以创立排序二叉树:\n");scanf_s("%d", &k.key);for (i = 0; k.key != NULL; i++){//判断是否重复if (!SearchBST(BT, k.key, NULL, p)){InsertBST(BT, k);scanf_s("%d", &k.key);}else{printf("输入数据重复!\n");return;}}}插入int InsertBST(BiTree &T, ElemType e){BiTree s, p;if (!SearchBST(T, e.key, NULL, p)){s = (BiTree)malloc(sizeof(BiTNode));s->data = e;s->lchild = s->rchild = NULL;if (!p)T = s;else if LT(e.key, p->data.key)p->lchild = s;elsep->rchild = s;return TRUE;}else return FALSE;}删除//某个节点元素的删除int DeleteEle(BiTree &p){BiTree q, s;if (!p->rchild) //右子树为空{q = p;p = p->lchild;free(q);}else if (!p->lchild) //左子树为空{q = p;p = p->rchild;free(q);}else{q = p;s = p->lchild;while (s->rchild){q = s;s = s->rchild;}p->data = s->data;if (q != p)q->rchild = s->lchild;elseq->lchild = s->lchild;delete s;}return TRUE;}//整棵树的删除int DeleteBST(BiTree &T, KeyType key) //实现二叉排序树的删除操作{if (!T){return FALSE;}else{if (EQ(key, T->data.key)) //是否相等return DeleteEle(T);else if (LT(key, T->data.key)) //是否小于return DeleteBST(T->lchild, key);elsereturn DeleteBST(T->rchild, key);}return 0;}二叉树的前中后根遍历栈的定义typedef struct{SElemType *base;SElemType *top;int stacksize;}SqStack;int InitStack(SqStack &S) //构造空栈{S.base = (SElemType*)malloc(STACK_INIT_SIZE *sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base;S.stacksize = STACK_INIT_SIZE;return OK;}//InitStackint Push(SqStack &S, SElemType e) //插入元素e为新栈顶{if (S.top - S.base >= S.stacksize){S.base = (SElemType*)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemType));if (!S.base) exit(OVERFLOW);S.top = S.base + S.stacksize;S.stacksize += STACKINCREMENT;}*S.top++ = e;return OK;}//Pushint Pop(SqStack &S, SElemType &e) //删除栈顶,应用e返回其值{if (S.top == S.base) return ERROR;e = *--S.top;return OK;}//Popint StackEmpty(SqStack S) //判断是否为空栈{if (S.base == S.top) return TRUE;return FALSE;}先根遍历int PreOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);if (!Visit(p->data)) return ERROR;p = p->lchild;}else{Pop(S, p);p = p->rchild;}}return OK;}中根遍历int InOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S;BiTree p;InitStack(S);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);p = p->lchild;}else{Pop(S, p);if (!Visit(p->data)) return ERROR;p = p->rchild;}}return OK;}后根遍历int PostOrderTraverse(BiTree T, int(*Visit)(ElemType e)) {SqStack S, SS;BiTree p;InitStack(S);InitStack(SS);p = T;while (p || !StackEmpty(S)){if (p){Push(S, p);Push(SS, p);p = p->rchild;}else{if (!StackEmpty(S)){Pop(S, p);p = p->lchild;}}}while (!StackEmpty(SS)){Pop(SS, p);if (!Visit(p->data)) return ERROR;}return OK;}利用数组存储一个班学生信息ElemType a[] = { 51, "陈继真", 88,82, "黄景元", 89,53, "贾成", 88,44, "呼颜", 90,25, "鲁修德", 88,56, "须成", 88,47, "孙祥", 87, 38, "柏有患", 89, 9, " 革高", 89, 10, "考鬲", 87, 31, "李燧", 86, 12, "夏祥", 89, 53, "余惠", 84, 4, "鲁芝", 90, 75, "黄丙庆", 88, 16, "李应", 89, 87, "杨志", 86, 18, "李逵", 89, 9, "阮小五", 85, 20, "史进", 88, 21, "秦明", 88, 82, "杨雄", 89, 23, "刘唐", 85, 64, "武松", 88, 25, "李俊", 88, 86, "卢俊义", 88, 27, "华荣", 87, 28, "杨胜", 88, 29, "林冲", 89, 70, "李跃", 85, 31, "蓝虎", 90, 32, "宋禄", 84, 73, "鲁智深", 89, 34, "关斌", 90, 55, "龚成", 87, 36, "黄乌", 87, 57, "孔道灵", 87, 38, "张焕", 84, 59, "李信", 88, 30, "徐山", 83, 41, "秦祥", 85, 42, "葛公", 85, 23, "武衍公", 87, 94, "范斌", 83, 45, "黄乌", 60, 67, "叶景昌", 99, 7, "焦龙", 89, 78, "星姚烨", 85, 49, "孙吉", 90, 60, "陈梦庚", 95,};数组查询函数void ArraySearch(ElemType a[], int key, int length){int i;for (i = 0; i <= length; i++){if (key == a[i].key){cout << "学号:" << a[i].key << " 姓名:" << a[i].name << " 成绩:" << a[i].grade << endl;break;}}}二叉树查询函数上文二叉树根本函数中的SearchBST()即为二叉树查询函数。

数据结构二叉树学习教案

数据结构二叉树学习教案

[1]
A
[2]
B
[3]
C
[4]
D
[5]
E
般不用
[6] [7] [8] [9]
F G H I
A
一 、顺序 存储结 构 按 二 叉 树 的 结点“ 自上而 下、从 左至右 ”编号 ,用一 组连续 (liánxù)的 存储 单元存 储。
B
C
D EF G
H
I
问:顺序存储后能否复原成唯一对应(duìyìng)的二叉树形状? 答:若是完全/满二叉树则可以做到唯一复原。
right_child
data
left_child
right_child
第6页/共17页
第七页,共16页。
二 叉 树 结 点 (jié diǎn)数 据 类 型 定 义 : typedef stru ct B iTNod e {
TElemT ype d ata; struct BiTN ode *lef t_chi ld, *righ t_ch ild; } BiTNo de, * BiTr ee;
f
d
b
e
ac
g i
h
j
第14页/共17页
第十五页,共16页。
习题2:若一棵二叉树,左右子树均有三个结点,其左子树的前 (先)序序列与中序序列相同,右子树的中序序列与后序 序列相同,试构造该树。
习题3:一棵非空的二叉树其先序序列和后序序列正好相反,画出 这棵二叉树的形状。
习题4:已知一棵完全二叉树共有892个结点,试求:⑴ 树的高度; ⑵ 叶结点数;⑶ 单支(度为1)结点数;⑷ 最后(zuìhòu)一 个非终端结点的序号。
第9页/共17页
第十页,共16页。

二叉树的遍历教案

二叉树的遍历教案

课题二叉树的遍历学习目标:1、知识与技能掌握二叉树三种遍历的遍历原则和方法2、过程与方法通过体验、分析、讲授和实践探究,学会遍历二叉树3情感态度与价值观(!)通过遍历学习,培养学生细致严谨的思维习惯(2)促进学生对算法学习的热情,学习在平时生活中建模思想。

学情分析:本学期高一学生刚刚学习完数学选修科目3《算法》,对数据流程有比较深刻的认知,具备探究树理论的基础。

重难点:重点:二叉树特征;难点:二叉树的遍历规则的实际使用。

教学过程:活动一:一起游戏——汉诺塔游戏介绍:汉诺塔是一款WP7平台上源于印度一个古老传说的益智类游戏。

传说上帝创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。

上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

游戏玩法:游戏里有三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。

玩家需要做的是把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

活动二:二叉树1 特点:一棵由一个结点和两棵互不相交的分别称作根的左子树和右子树所组成的非空树,左右子树又同样都是二叉树。

遍历是对二叉树树的一种最基本的运算,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。

2 几种遍历(1)前序遍历:中序遍历后序遍历(2)遍历规则步骤第一第二第三名称前序遍历访问根结点前序遍历左子树前序遍历右子树中序遍历中序遍历左子树访问根结点中序遍历右子树后序遍历后序遍历左子树后序遍历右子树风味根结点备注二叉树非空活动三:完成图5二叉树的前序遍历abcdeghi图5活动四:分组讨论完成右图二叉树的中序遍历和后序遍历中序CBDAEGF后序:CDBGFEA活动五:讨论探究完成图5二叉树的中序遍历和后序遍历中序:CBAFEGDHI后序:CBFGEIHDA活动五:知识拓展:1假设前序遍历是adbgcefh,中序遍历是dgbaechf,请你推演出该二叉树;2假设后序遍历是gbdehfca,中序遍历是dgbaechf,请你推演出该二叉树的前序遍历节奏把控:前序遍历是先访问根节点,然后再访问子树的,而中序遍历则先访问左子树再访问根节点,那么把前序的a 取出来,然后查找a 在中序遍历中的位置就得到dgb a echf 这样我们就知道dgb 是左子树echf 是右子树,因为数量要吻合所以前序中相应的dbg 是左子树cefh 是右子树。

算术表达式与二叉树课程设计

算术表达式与二叉树课程设计

山西大学课程设计任务书设计题目算术表达式与二叉树所属课程:数据结构系别软件学院专业软件工程班级软工1408班姓名霍志斌指导教师李雪梅设计任务下达日期 2015年 12 月15 日设计时间2016年1月4日至 2016年1月8日目录:一、需求分析二、概要设计1、数据类型的声明:2、表达式的抽象数据类型定义3、整体设计三、详细设计1、二叉树的存储类型2、顺序栈的存储类型3、表达式的基本操作4、主程序和其他伪码算法5、函数的调用关系四、设计和调试分析五、测试六、课程设计的心得和心得以及问题一、需求分析【课程设计要求】【问题的描述】一个表达式和一棵二叉树之间,存在着自然的对应关系。

写一个程序,实现基于二叉树表示的算术表达式Expression的操作。

【基本要求】假设算术表达式Expression内可以含有变量(a-z),常量(0-9)和二元运算符(+,-,*,/,^(乘幂))。

实现以下操作:(1)ReadExpr(E)――以字符序列的形式输入语法正确的前缀表达式并构造表达式E。

(2)WriteExpr(E)――用带括号的中缀表达式输出表达式E。

(3)Assign(V,c)――实现对变量V的赋值(V=c),变量的初值为0。

(4)Value(E)――对算术表达式E求值。

(5)CompoundExpr(p,E1,E2)――构造一个新的复合表达式(E1)p(E2)。

【测试数据】1)分别输入0;a;-91;+a*bc;+*5x2*8x;+++*3^*2^x2x6并输出。

2)每当输入一个表达式后,对其中的变量赋值,然后对表达式求值。

二、概要设计1、数据类型的声明:在这个课程设计中,采用了链表二叉树的存储结构,以及两个顺序栈的辅助存储结构/*头文件以及存储结构*/#include<stdio.h>#include<conio.h>#include<stdlib.h>#include<string.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW 0typedef int Status;2、表达式的抽象数据类型定义ADT Expression{数据对象D:D是具有数值的常量C和没有数值的变量V;数据关系:R={<(V或者C)P(V或者C)>|V,C∈D, <(V或者C)P(V或者C)>表示由运算符P结合起来的表达式E}基本操作:Status Input_Expr(&string,flag)操作结果:以字符序列的形式输入语法正确的前缀表达式,保存到字符串string;参数flag表示输出的提示信息是什么,输入成功返回OK,否则,返回ERROR。

二叉树的遍历教案

二叉树的遍历教案

课题二叉树的遍历学习目标:1、知识与技能掌握二叉树三种遍历的遍历原则和方法2、过程与方法通过体验、分析、讲授和实践探究,学会遍历二叉树3情感态度与价值观(!)通过遍历学习,培养学生细致严谨的思维习惯(2)促进学生对算法学习的热情,学习在平时生活中建模思想。

学情分析:本学期高一学生刚刚学习完数学选修科目3《算法》,对数据流程有比较深刻的认知,具备探究树理论的基础。

重难点:重点:二叉树特征;难点:二叉树的遍历规则的实际使用。

教学过程:活动一:一起游戏——汉诺塔游戏介绍:汉诺塔是一款WP7平台上源于印度一个古老传说的益智类游戏。

传说上帝创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。

上帝命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

游戏玩法:游戏里有三根金刚石柱子,在一根柱子上从下往上安大小顺序摞着64片黄金圆盘。

玩家需要做的是把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。

并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

活动二:二叉树1 特点:一棵由一个结点和两棵互不相交的分别称作根的左子树和右子树所组成的非空树,左右子树又同样都是二叉树。

遍历是对二叉树树的一种最基本的运算,就是按一定的规则和顺序走遍二叉树的所有结点,使每一个结点都被访问一次,而且只被访问一次。

2 几种遍历(1)前序遍历:中序遍历后序遍历(2)遍历规则步骤第一第二第三名称前序遍历访问根结点前序遍历左子树前序遍历右子树中序遍历中序遍历左子树访问根结点中序遍历右子树后序遍历后序遍历左子树后序遍历右子树风味根结点备注二叉树非空活动三:完成图5二叉树的前序遍历abcdeghi图5活动四:分组讨论完成右图二叉树的中序遍历和后序遍历中序CBDAEGF后序:CDBGFEA活动五:讨论探究完成图5二叉树的中序遍历和后序遍历中序:CBAFEGDHI后序:CBFGEIHDA活动五:知识拓展:1假设前序遍历是adbgcefh,中序遍历是dgbaechf,请你推演出该二叉树;2假设后序遍历是gbdehfca,中序遍历是dgbaechf,请你推演出该二叉树的前序遍历节奏把控:前序遍历是先访问根节点,然后再访问子树的,而中序遍历则先访问左子树再访问根节点,那么把前序的a 取出来,然后查找a 在中序遍历中的位置就得到dgb a echf 这样我们就知道dgb 是左子树echf 是右子树,因为数量要吻合所以前序中相应的dbg 是左子树cefh 是右子树。

二叉树教案

二叉树教案

二叉树教案一、教学目标:1.了解二叉树的定义和性质。

2.学会二叉树的遍历算法(前序遍历、中序遍历、后序遍历)。

3.掌握二叉树的基本操作(创建二叉树、插入节点、删除节点)。

二、教学重点和难点:1.二叉树的定义和性质。

2.二叉树的遍历算法。

3.二叉树的基本操作。

三、教学准备:1.教师准备:PPT、计算机、投影仪。

2.学生准备:课前预习、纸笔。

四、教学过程:Step 1 导入新课教师通过提问的方式,引导学生回顾树的基本概念,并激发学生对二叉树的兴趣。

Step 2 二叉树的定义和性质教师给出二叉树的定义,并带领学生讨论二叉树的性质(每个节点最多有两个子节点,左子树和右子树)。

Step 3 二叉树的遍历算法1.前序遍历:先访问根节点,然后递归遍历左子树,再递归遍历右子树。

2.中序遍历:先递归遍历左子树,然后访问根节点,再递归遍历右子树。

3.后序遍历:先递归遍历左子树,然后递归遍历右子树,最后访问根节点。

Step 4 二叉树的基本操作1.创建二叉树:教师通过示例向学生展示二叉树的创建过程。

2.插入节点:教师通过示例向学生展示如何插入节点,并解释插入节点的规则。

3.删除节点:教师通过示例向学生展示如何删除节点,并解释删除节点的规则。

Step 5 练习与拓展1.教师设计练习题,让学生运用所学知识进行练习。

2.鼓励学生拓展二叉树的其他应用领域,并进行讨论。

五、教学反思本节课通过讲解二叉树的定义和性质,以及二叉树的遍历算法和基本操作,使学生对二叉树有了基本的了解和掌握。

通过练习和拓展,巩固了学生的学习成果,并培养了学生的分析和解决问题的能力。

但是,由于时间有限,学生的实际操作机会较少,可以在课后布置相关的作业,加深学生的理解和应用能力。

数据结构_二叉树的遍历_课程设计

数据结构_二叉树的遍历_课程设计

8
if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } } void postorder(bitree *bt)/*后序序遍历二叉树*/ { if(bt!=NULL) { postorder(bt->lchild); postorder(bt->rchild); printf("%c",bt->data); } }
3.2.2 二叉树的中序递归遍历算法
void inorder(bitree *bt)/*中序序遍历二叉树*/ { if(bt!=NULL)/*二叉树 bt 非空*/ { inorder(bt->lchild);/*中序遍历 bt 的左子树*/ printf("%c",bt->data);/*访问结点 bt*/ inorder(bt->rchild);/*中序遍历 bt 的右子树*/ } }
图 1 “菜单”界面
图2
创建二叉树
5
图 3 二叉树的先序遍历
图4
二叉树的中序输出
6
图 5 二叉树的后序输出
五:实验总结 虽然做的过程中出现很多错误。但是最后还是一一纠正了,并在其中发现了自 身的不足,补学补差。最后终于完成了。
六:源程序附录
#include<stdio.h> #include<stdlib.h> typedef char datatype; typedef struct node { datatype data;/*数据元素*/ struct node *lchild,*rchild;/*指向左,右孩子*/ }bitree; bitree *root;/*二叉树结点类型定义*/ bitree *creatbitree(bitree *root)/*创建二叉树*/ { char ch;

数据结构详细教案——树与二叉树

数据结构详细教案——树与二叉树

数据结构详细教案——树与二叉树一、教学目标1.了解树和二叉树的基本概念和特点;2.掌握树和二叉树的基本操作;3.能够通过递归遍历树和二叉树。

二、教学重难点1.树和二叉树的基本概念和特点;2.递归遍历树和二叉树。

三、教学内容1.树的概念和特点1.1树的定义树是n(n>=0)个节点的有限集。

当n=0时,称为空树;如果不为空树,则1. 树有且仅有一个特殊节点被称为根(Root);2.其余节点可分为m(m>0)个互不相交的有限集T1,T2,...,Tm,其中每个集合又是一棵树。

1.2节点间的关系- 父节点(parent)是当前节点的直接上级节点;- 子节点(child)是当前节点的直接下级节点;- 兄弟节点(sibling)是具有同一父节点的节点;- 祖先节点(ancestor)是通过从当前节点到根的任意路径可以到达的节点;- 子孙节点(descendant)是通过从该节点到子树的任意节点可以到达的节点。

1.3树的特点-树是一个有层次的结构,可以看作是一个鱼骨图;-树中的每个节点都可以有多个子节点,但只有一个父节点;-树中的节点之间是唯一的,不存在重复节点;-树中的任意两个节点之间都有且仅有一条路径连接。

2.二叉树的概念和特点2.1二叉树的定义二叉树是一种特殊的树结构,它的每个节点最多只能有两个子节点,分别称为左子节点和右子节点。

2.2二叉树的特点-二叉树的度最大为2,即每个节点最多有两个子节点;-二叉树的第i层最多有2^(i-1)个节点;-对于任意一颗二叉树,如果其叶子节点数为n0,度为2的节点数为n2,则有n0=n2+1;-完全二叉树是一种特殊的二叉树,除了最后一层的叶子节点外,每一层的节点都是满的。

四、教学过程1.讲解树和二叉树的基本概念和特点,引导学生理解树和二叉树的定义和节点间的关系。

2.分析树和二叉树的基本操作,并通过实例演示操作过程,让学生掌握操作的步骤和方法。

3.运用递归算法遍历树和二叉树的过程,详细讲解前序遍历、中序遍历和后序遍历的定义和实现方法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

安徽理工大学数据结构课程设计说明书题目: 二叉树的遍历集成院系:计算机科学与工程学院专业班级:学号:学生姓名:指导教师:2015年 01 月 9 日安徽理工大学课程设计(论文)任务书计算机科学与工程学院信息安全教研室2014年 12 月 18 日目录1.需求分析 (1)2、总体设计 (1)2.1 程序目录 (1)2.2 算法流程 (3)3、详细设计 (3)3.1 界面设计 (3)3.2 详细代码设计 (5)3.3 调试分析 (10)4、总结 (15)参考文献 (16)代码详述 (16)1.需求分析“数据结构”是计算机程序设计的重要理论技术基础,它不仅是计算机学科的核心,而且也成为其他理工类学科必修课程,所谓”数据结构”是相互之间存在一种或多种特定关系的数据元素的集合.数据元素之间的相互关系成为结构,结构一般有线性结构,树形结构,图状结构,本程序所做的就是树形结构的二叉树的遍历算法和线索化查找.本程序使用VC6.0++编写,具体实现功能有二叉树的遍历,包括先序遍历,中序遍历,后序遍历的递归算法以及非递归算法.另外本程序还有可线索化二叉树的功能,由此可以得到二叉树某个节点的前驱和后继.题目要求为:1.实现二叉树的各种遍历。

包括先序遍历、中序遍历、后序遍历的递归和非递归算法、以及层次遍历。

2.要求能查找任一结点在某种遍历序列中的前驱和后继。

3.界面友好,易于操作。

可采用菜单或其它人机对话方式进行选择。

由小组一起制作,本人做小组汇总工作,并在基础上加了查找某个节点是否存在二叉树,以及求二叉树总节点数等一些简单功能2、总体设计2.1 程序目录(1)typedef struct node二叉树的定义,包含数据域data,左孩子lchild,右孩子rchild,若二叉树为空,则头结点指向空指针,并且data数据域为字符型数据.(2)BiTree CreatBiTree1(BiTree &T)创建一颗二叉树,需要按照先序遍历输入相应字符才能构造出二叉树,其中用星号”*”来代表空字符.(3)void Preorder1(BiTree T)先序遍历递归算法,调用此函数可以获得输入二叉树的先序序列(4)void Preorder2(BiTree T)先序遍历非递归算法,和上面一样,调用此函数可以获得二叉树先序序列(5)void Inorder1(BiTree T)中序遍历递归算法,调用此函数可以获得输入二叉树的中序序列(6)void Inorder2(BiTree T)中序遍历非递归算法,和上面一样,调用此函数可以获得二叉树中序序列(7)void Postorder1(BiTree T)后序遍历递归算法,调用此函数可以获得输入二叉树的后序序列(8)void Postorder2(BiTree &T)和typedef struct stacknode后序遍历非递归算法,和其中用到的哨兵结构体.调用此函数可以获得二叉树后序序列(9)void Levelorder(BiTree T,int NodeNum)层序遍历二叉树,需要手动输入节点数,然后即可进行二叉树的层序遍历,输出遍历结果(10)void InThreading(BiTree p)线索化二叉树中需要用到的线索化前驱和后继(11)void InOrderThreading(BiTree &Thrt,BiTree T)以中序遍历来线索化二叉树,让空节点分别指向当前节点的前驱后继(12)BiTree Inprenode(BiTree p)和BiTree Inpostnode(BiTree p)线索化后用此函数查找二叉树的前驱和后继(13)BiTree search(BiTree BT,char x)查找某个二叉树节点,其中x为要查找节点的data域的值(14)main( )主函数利用while()和switch()语句构造可视化友好界面 2.2 算法流程小组分工设计独立的函数,比如三种遍历,层序遍历,二叉树线索化等,然后再综合起来,用主函数调用即可33.1 界面设计(1)打开程序后首先是按照先序序列输入二叉树,其中用“*”号表示空节点。

mainCreatBiTree Inorder1Preorder2 Preorder1Inorder2 Levelorder Postorder1 Postorder2InThreading InOrderThre Inprenode search图1 二叉树输入界面(2)输入完二叉树后进入功能选择页面,选择对应的编号,实行相应的操作图2 二叉树功能选择页面3.2 详细代码设计(1)创建一个二叉树,用户按照二叉树先序遍历顺序输入相应data域数据,使用getchar()读入并赋给c,利用T节点,以及左右递归,即可建立出一颗二叉树。

BiTree CreatBiTree1(BiTree &T){char ch;if((ch=getchar())=='*')T=NULL; //读入星号,返回空指针else{T=(BiTNode *)malloc(sizeof(BiTNode));//生成结点if(!T)return 0;T->data=ch;T->LTag=0;T->RTag=0;CreatBiTree1(T->lchild); //构造左子树CreatBiTree1(T->rchild); //构造右子树return(T);}}(2)先序递归算法,读取头节点后,输出,接下来使用递归算法,不断地向下延伸读取,输出即可。

void Preorder1(BiTree T){if(T) {printf("%c",T->data); //访问结点Preorder1(T->lchild); //先序遍历左子树Preorder1(T->rchild); //先序遍历右子树}}(3)先序遍历非递归算法,设置一个stack的栈用来存储读取的二叉树序列,利用栈先进后出的特性,输出栈即为先序遍历.void Preorder2(BiTree T){ B iTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){printf("%c",p->data);stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];p=p->rchild;}}}}(4)中序遍历递归算法和先序遍历思想差不多,只是在遍历完左边后再输出头节点.void Inorder1(BiTree T){if(T) {Inorder1(T->lchild); //中序遍历左子树printf("%c",T->data); //访问结点Inorder1(T->rchild); //中序遍历右子树}}(5)中序遍历非递归算法,同理也是利用栈的特性来存储读取出来的data域的值,修改下出栈方式即可.void Inorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];printf("%c",p->data);p=p->rchild;}}}}(6)后序遍历递归算法和先序遍历思想差不多,只是在遍历完最后后再输出头节点.void Postorder1(BiTree T){if(T) {Postorder1(T->lchild); //后序遍历左子树Postorder1(T->rchild); //后序遍历右子树printf("%c",T->data); //访问结点}}(7)后序遍历非递归算法,首先设置一个typedef struct stacknode的结构体为监查哨兵,输出过的节点都做上标记,防止二次输出.typedef struct{BiTree ptr;int tag;}stacknode; //设置哨兵void Postorder2(BiTree &T){ stacknode s[Max],x;BiTree p=T;int top;if(T!=NULL){top=0;p=T;do{while(p!=NULL){s[top].ptr=p;s[top].tag=1;top++;p=p->lchild;}while(top>0&&s[top-1].tag==2){x=s[--top];p=x.ptr;printf("%c",p->data);}if(top>0){s[top-1].tag=2;p=s[top-1].ptr->rchild;}}while(top>0);}}(8)层序遍历二叉树,利用指针数组*cq[Max]进行出队入队操作,再遍历左子树,最后再遍历右子树.void Levelorder(BiTree T,int NodeNum){int front=0,rear=1;BiTNode *cq[Max],*p; //定义结点的指针数组cqcq[1]=T; //根入队while(front!=rear){front=(front+1)%NodeNum;p=cq[front]; //出队printf("%c",p->data); //出队,输出结点的值if(p->lchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->lchild; //左子树入队}if(p->rchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->rchild; //右子树入队} }}(9)线索化二叉树,利用void InThreading(BiTree p)和void InOrderThreading(BiTree &Thrt,BiTree T)可完成二叉树中序线索化.主要思想是使二叉树中的空节点指向其前驱和后继.void InThreading(BiTree p)//线索化二叉树前驱后继{if(p){InThreading(p->lchild);if(!p->lchild){p->LTag=1;p->lchild=pre;}if(!pre->rchild){pre->RTag=1;pre->rchild=p;}pre=p;InThreading(p->rchild);}}void InOrderThreading(BiTree &Thrt,BiTree T){Thrt=(BiTree)malloc(sizeof(BiTNode));Thrt->LTag=0;Thrt->RTag=1;Thrt->rchild=Thrt;if(!T)Thrt->lchild=Thrt;else{Thrt->lchild=T;pre=Thrt;InThreading(T);pre->rchild=Thrt;pre->RTag=1;Thrt->rchild=pre;}}(10)查找二叉树的前驱和后继,基于中序线索化二叉树后,根据LTag和RTag的只能即可确定出节点的前驱和后继.BiTree Inprenode(BiTree p)//查找前驱{BiTree pre;pre=p->lchild;if (p->LTag!=1)while(pre->RTag==0)pre=pre->rchild;return(pre);}BiTree Inpostnode(BiTree p)//查找后继{BiTree post;post=p->rchild;if (p->RTag!=1)while(post->LTag==0)post=post->lchild;return(post);}(11)查找某个二叉树节点.根据data域的值,可以利用递归遍历查找出二叉树的对应节点的data域的值,从而确定所要查询的节点是否在二叉树中.BiTree search(BiTree BT,char x)//查找结点X,BiTree是二叉树结点类型的指针{if(BT->data==x) return BT;else if(BT->lchild)return search(BT->lchild,x);else if(BT->rchild)return search(BT->rchild,x);elsereturn NULL;}3.3 调试分析(1)先序递归遍历图3 二叉树先序递归遍历(2)先序非递归遍历图4 二叉树先序非递归遍历(3)中序递归遍历图5 二叉树中序递归遍历(4)中序非递归遍历图6 二叉树中序非递归遍历(5)后序递归遍历图7 二叉树后序递归遍历(6)后序非递归遍历图8 二叉树后序非递归遍历(7)层序遍历图8 层序遍历二叉树(8)查找二叉树节点的前驱和后继图9 查找前驱和后继(9)判断节点是否在二叉树内图10 判断节点是否在二叉树内4、总结数据结构是一门博大精深的课程,尤其是通过这次课程设计,我深切是了解到算法为何是程序的灵魂了,算法决定一个程序的好与坏,效率高与效率低.在以前的c语言学习中,编写的程序大多数都是简短的实现单一功能的程序,没有了解到程序与程序之间的联系,和不同算法之间是如何相联系的.而这次试验却完全不一样.编写程序前需要自己做一个好的规划和设计,不断去了解所需要的编写的功能概念和算法,一开始总是很难,但随着不断地深入,我渐渐喜欢上了这种不断探索的过程,当然程序是不断出错的,而一次又一次的解决错误的过程,却使我体会到成功的喜悦.最终在自己的努力下,程序可以运行起来,实现自己所需要的功能,这是一件自豪的事情.通过这次试验,我也体会到数据结构的重要性,只有真正理解数据类型的区别和数据类型之间的转换,才能更好地做出程序,比如查找前驱和后继的时候用户输入的是char型的数据,而查找函数需要的是BiTree的结构体数据,因为就需要search函数来转化,找到这个节点,从而查找出前驱和后继,这就是数据利用的一小点,而这一小点,让我在程序设计中避免了好多错误,巧妙地利用数据之间的关系,就可以灵活的调用函数,而避免出错.这次试验中我有一个疑惑的部分,我输入data数据,使用scanf(“%c”,ch),在运行过程中却没法输入,这个令我很疑惑,我将程序改为cin>>ch;就可以了,我认为%c 字符把enter当成字符了,而cin却不把enter当成字符,所以可以输入.像这样的小问题,我不断发现,不断解决,最终提高自己,感受到数据结构的魅力,参考文献[1]严蔚敏,吴伟民.数据结构(C语言版).北京:清华大学出版社,1997.4代码详述#include"stdio.h"#include"string.h"#include"malloc.h"#include <iostream>using namespace std;#define Max 20 //结点的最大个数typedef struct node{char data;struct node *lchild,*rchild;int LTag,RTag,flag;//用于线索化二叉树}BiTNode,*BiTree; //自定义二叉树的结点类型BiTree pre;//用于线索化int NodeNum; //NodeNum为结点数//二叉树线索化之前先输入二叉树BiTree CreatBiTree1(BiTree &T){char ch;if((ch=getchar())=='*')T=NULL; //读入星号,返回空指针else{T=(BiTNode *)malloc(sizeof(BiTNode));//生成结点if(!T)return 0;T->data=ch;T->LTag=0;T->RTag=0;CreatBiTree1(T->lchild); //构造左子树CreatBiTree1(T->rchild); //构造右子树return(T);}}//DLR 先序遍历递归算法void Preorder1(BiTree T){if(T) {printf("%c",T->data); //访问结点Preorder1(T->lchild); //先序遍历左子树Preorder1(T->rchild); //先序遍历右子树}}//DLR 先序遍历非递归算法void Preorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){printf("%c",p->data);stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];p=p->rchild;}}}}//LDR 中序遍历递归算法void Inorder1(BiTree T){if(T) {Inorder1(T->lchild); //中序遍历左子树printf("%c",T->data); //访问结点Inorder1(T->rchild); //中序遍历右子树}}//LDR 中序遍历非递归算法void Inorder2(BiTree T){ BiTree stack[Max],p;int top;if( T!=NULL){top=0;p=T;while(p!=NULL||top>0){while(p!=NULL){stack[top]=p;top++;p=p->lchild;}if(top>0){ top--;p=stack[top];printf("%c",p->data);p=p->rchild;}}}}//LRD 后序遍历递归算法void Postorder1(BiTree T){if(T) {Postorder1(T->lchild); //后序遍历左子树Postorder1(T->rchild); //后序遍历右子树printf("%c",T->data); //访问结点}}//LRD 后序遍历非递归算法typedef struct{BiTree ptr;int tag;}stacknode; //设置哨兵void Postorder2(BiTree &T){ stacknode s[Max],x;BiTree p=T;int top;if(T!=NULL){top=0;p=T;do{while(p!=NULL){s[top].ptr=p;s[top].tag=1;top++;p=p->lchild;}while(top>0&&s[top-1].tag==2){x=s[--top];p=x.ptr;printf("%c",p->data);}if(top>0){s[top-1].tag=2;p=s[top-1].ptr->rchild;}}while(top>0);}}//层次遍历二叉树void Levelorder(BiTree T,int NodeNum){int front=0,rear=1;BiTNode *cq[Max],*p; //定义结点的指针数组cqcq[1]=T; //根入队while(front!=rear){front=(front+1)%NodeNum;p=cq[front]; //出队printf("%c",p->data); //出队,输出结点的值if(p->lchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->lchild; //左子树入队}if(p->rchild!=NULL){rear=(rear+1)%NodeNum;cq[rear]=p->rchild; //右子树入队}}}//中序遍历下节点的前驱后继void InThreading(BiTree p)//线索化二叉树前驱后继{if(p){InThreading(p->lchild);if(!p->lchild){p->LTag=1;p->lchild=pre;}if(!pre->rchild){pre->RTag=1;pre->rchild=p;}pre=p;InThreading(p->rchild);}}void InOrderThreading(BiTree &Thrt,BiTree T){Thrt=(BiTree)malloc(sizeof(BiTNode));Thrt->LTag=0;Thrt->RTag=1;Thrt->rchild=Thrt;if(!T)Thrt->lchild=Thrt;else{Thrt->lchild=T;pre=Thrt;InThreading(T);pre->rchild=Thrt;pre->RTag=1;Thrt->rchild=pre;}}BiTree Inprenode(BiTree p)//查找前驱{BiTree pre;pre=p->lchild;if (p->LTag!=1)while(pre->RTag==0)pre=pre->rchild;return(pre);}BiTree Inpostnode(BiTree p)//查找后继{BiTree post;post=p->rchild;if (p->RTag!=1)while(post->LTag==0)post=post->lchild;return(post);}//查找某个节点BiTree search(BiTree BT,char x)//查找结点X,BiTree是二叉树结点类型的指针{if(BT->data==x) return BT;else if(BT->lchild)return search(BT->lchild,x);else if(BT->rchild)return search(BT->rchild,x);elsereturn 0;}//主函数int main(){BiTree root,t,k1;char c;int i;printf("\n");printf("创建二叉树; 输入完全二叉树的先序序列:"); //输入完全二叉树的先序序列,// 用*代表虚结点,如ABD###CE##F## CreatBiTree1(root); //创建二叉树,返回根结点do { //从菜单中选择遍历方式,输入序号。

相关文档
最新文档