建立二叉树-并对树进行操作数据结构课程设
数据结构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()即为二叉树查询函数。
数据结构实验五(二叉树的建立及遍历)题目和源程序

实验5:二叉树的建立及遍历(第十三周星期三7、8节)一、实验目的1.学会实现二叉树结点结构和对二叉树的基本操作。
2.掌握对二叉树每种操作的具体实现,学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
二、实验要求1.认真阅读和掌握和本实验相关的教材内容。
2.编写完整程序完成下面的实验内容并上机运行。
3.整理并上交实验报告。
三、实验内容1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序、中序、后序)对这棵二叉树进行遍历并计算出二叉树的高度。
2 .编写程序生成下面所示的二叉树,并采用中序遍历的非递归算法对此二叉树进行遍历。
四、思考与提高1.如何计算二叉链表存储的二叉树中度数为1的结点数?2.已知有—棵以二叉链表存储的二叉树,root指向根结点,p指向二叉树中任一结点,如何求从根结点到p所指结点之间的路径?/*----------------------------------------* 05-1_递归遍历二叉树.cpp -- 递归遍历二叉树的相关操作* 对递归遍历二叉树的每个基本操作都用单独的函数来实现* 水上飘2009年写----------------------------------------*/// ds05.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>typedef char ElemType;using namespace std;typedef struct BiTNode {ElemType data;//左右孩子指针BiTNode *lchild, *rchild;}BiTNode, *BiTree;//动态输入字符按先序创建二叉树void CreateBiTree(BiTree &T) {char ch;ch = cin.get();if(ch == ' ') {T = NULL;}else {if(ch == '\n') {cout << "输入未结束前不要输入回车,""要结束分支请输入空格!" << endl;}else {//生成根结点T = (BiTNode * )malloc(sizeof(BiTNode));if(!T)cout << "内存分配失败!" << endl;T->data = ch;//构造左子树CreateBiTree(T->lchild);//构造右子树CreateBiTree(T->rchild);}}}//输出e的值ElemType PrintElement(ElemType e) { cout << e << " ";return e;}//先序遍历void PreOrderTraverse(BiTree T) { if (T != NULL) {//打印结点的值PrintElement(T->data);//遍历左孩子PreOrderTraverse(T->lchild);//遍历右孩子PreOrderTraverse(T->rchild);}}//中序遍历void InOrderTraverse(BiTree T) {if (T != NULL) {//遍历左孩子InOrderTraverse(T->lchild);//打印结点的值PrintElement(T->data);//遍历右孩子InOrderTraverse(T->rchild);}}//后序遍历void PostOrderTraverse(BiTree T) { if (T != NULL) {//遍历左孩子PostOrderTraverse(T->lchild);//遍历右孩子PostOrderTraverse(T->rchild);//打印结点的值PrintElement(T->data);}}//按任一种遍历次序输出二叉树中的所有结点void TraverseBiTree(BiTree T, int mark) {if(mark == 1) {//先序遍历PreOrderTraverse(T);cout << endl;}else if(mark == 2) {//中序遍历InOrderTraverse(T);cout << endl;}else if(mark == 3) {//后序遍历PostOrderTraverse(T);cout << endl;}else cout << "选择遍历结束!" << endl;}//输入值并执行选择遍历函数void ChoiceMark(BiTree T) {int mark = 1;cout << "请输入,先序遍历为1,中序为2,后序为3,跳过此操作为0:";cin >> mark;if(mark > 0 && mark < 4) {TraverseBiTree(T, mark);ChoiceMark(T);}else cout << "此操作已跳过!" << endl;}//求二叉树的深度int BiTreeDepth(BiTNode *T) {if (T == NULL) {//对于空树,返回0并结束递归return 0;}else {//计算左子树的深度int dep1 = BiTreeDepth(T->lchild);//计算右子树的深度int dep2 = BiTreeDepth(T->rchild);//返回树的深度if(dep1 > dep2)return dep1 + 1;elsereturn dep2 + 1;}}int _tmain(int argc, _TCHAR* argv[]){BiTNode *bt;bt = NULL; //将树根指针置空cout << "输入规则:" << endl<< "要生成新结点,输入一个字符,""不要生成新结点的左孩子,输入一个空格,""左右孩子都不要,输入两个空格,""要结束,输入多个空格(越多越好),再回车!"<< endl << "按先序输入:";CreateBiTree(bt);cout << "树的深度为:" << BiTreeDepth(bt) << endl;ChoiceMark(bt);return 0;}/*----------------------------------------* 05-2_构造二叉树.cpp -- 构造二叉树的相关操作* 对构造二叉树的每个基本操作都用单独的函数来实现* 水上飘2009年写----------------------------------------*/// ds05-2.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include <iostream>#define STACK_INIT_SIZE 100 //栈的存储空间初始分配量#define STACKINCREMENT 10 //存储空间分配增量typedef char ElemType; //元素类型using namespace std;typedef struct BiTNode {ElemType data; //结点值BiTNode *lchild, *rchild; //左右孩子指针}BiTNode, *BiTree;typedef struct {BiTree *base; //在栈构造之前和销毁之后,base的值为空BiTree *top; //栈顶指针int stacksize; //当前已分配的存储空间,以元素为单位}SqStack;//构造一个空栈void InitStack(SqStack &s) {s.base = (BiTree *)malloc(STACK_INIT_SIZE * sizeof(BiTree));if(!s.base)cout << "存储分配失败!" << endl;s.top = s.base;s.stacksize = STACK_INIT_SIZE;}//插入元素e为新的栈顶元素void Push(SqStack &s, BiTree e) {//栈满,追加存储空间if ((s.top - s.base) >= s.stacksize) {s.base = (BiTree *)malloc((STACK_INIT_SIZE+STACKINCREMENT) * sizeof(BiTree));if(!s.base)cout << "存储分配失败!" << endl;s.top = s.base + s.stacksize;s.stacksize += STACK_INIT_SIZE;}*s.top++ = e;}//若栈不空,则删除s的栈顶元素,并返回其值BiTree Pop(SqStack &s) {if(s.top == s.base)cout << "栈为空,无法删除栈顶元素!" << endl;s.top--;return *s.top;}//按先序输入字符创建二叉树void CreateBiTree(BiTree &T) {char ch;//接受输入的字符ch = cin.get();if(ch == ' ') {//分支结束T = NULL;} //if' 'endelse if(ch == '\n') {cout << "输入未结束前不要输入回车,""要结束分支请输入空格!(接着输入)" << endl;} //if'\n'endelse {//生成根结点T = (BiTNode * )malloc(sizeof(BiTree));if(!T)cout << "内存分配失败!" << endl;T->data = ch;//构造左子树CreateBiTree(T->lchild);//构造右子树CreateBiTree(T->rchild);} //Create end}//输出e的值,并返回ElemType PrintElement(ElemType e) {cout << e << " ";return e;}//中序遍历二叉树的非递归函数void InOrderTraverse(BiTree p, SqStack &S) {cout << "中序遍历结果:";while(S.top != S.base || p != NULL) {if(p != NULL) {Push(S,p);p = p->lchild;} //if NULL endelse {BiTree bi = Pop(S);if(!PrintElement(bi->data))cout << "输出其值未成功!" << endl;p = bi->rchild;} //else end} //while endcout << endl;}int _tmain(int argc, _TCHAR* argv[]){BiTNode *bt;SqStack S;InitStack(S);bt = NULL; //将树根指针置空cout << "老师要求的二叉树序列(‘空’表示空格):""12空空346空空空5空空,再回车!"<< endl << "请按先序输入一个二叉树序列(可另输入,但要为先序),""无左右孩子则分别输入空格。
数据结构-二叉排序树

二叉排序树操作一、设计步骤1)分析课程设计题目的要求2)写出详细设计说明3)编写程序代码,调试程序使其能正确运行4)设计完成的软件要便于操作和使用5)设计完成后提交课程设计报告(一)程序功能:1)创建二叉排序树2)输出二叉排序树3)在二叉排序树中插入新结点4)在二叉排序树中删除给定的值5)在二叉排序树中查找所给定的值(二)函数功能:1) struct BiTnode 定义二叉链表结点类型包含结点的信息2) class BT 二叉排序树类,以实现二叉排序树的相关操作3) InitBitree() 构造函数,使根节点指向空4) ~BT () 析构函数,释放结点空间5) void InsertBST(&t,key) 实现二叉排序树的插入功能6) int SearchBST(t,key) 实现二叉排序树的查找功能7) int DelBST(&t,key) 实现二叉排序树的删除功能8) void InorderBiTree (t) 实现二叉排序树的排序(输出功能)9) int main() 主函数,用来完成对二叉排序树类中各个函数的测试二、设计理论分析方法(一)二叉排序树定义首先,我们应该明确所谓二叉排序树是指满足下列条件的二叉树:(1)左子树上的所有结点值均小于根结点值;(2)右子数上的所有结点值均不小于根结点值;(3)左、右子数也满足上述两个条件。
根据对上述的理解和分析,我们就可以先创建出一个二叉链表结点的结构体类型(struct BiTNode)和一个二叉排序树类(class BT),以及类中的构造函数、析构函数和其他实现相关功能的函数。
(二)插入函数(void InsertBST(&t,key))首先定义一个与BiTNode<k> *BT同一类型的结点p,并为其申请空间,使p->data=key,p->lchild和p->rchild=NULL。
(完整版)数据结构实验教学手册

《数据结构》课程实验教学手册姓名:王俊东学号:1101120216专业:计算机科学与技术班级:2012 级 2 班任课教师:王爽时间:2013-2014 年度第1 学期综合成绩:许昌学院计算机科学与技术学院《数据结构》课程实验教学手册计算机科学与技术学院《数据结构》课程组实验手册使用及要求实验操作是教学过程中理论联系实际的重要环节,而实验报告的撰写又是知识系统化的吸收和升华过程,因此,实验报告应该体现完整性、规范性、正确性、有效性。
现将实验报告撰写的有关内容说明如下:1、实验预习报告必须在实验前完成。
2、实验时带好实验手册方可进行实验。
3、实验时按实验预习报告内容进行实验。
并如实填写实验过程及实验小结。
4、实验结束后填写通过后的源程序。
通过后的源程序可以手写也可以打印粘贴。
实验情况一览表实验一实验名称顺序表及其应用实验性质验证性实验学时数2学时printf("请选择正确的操作!\n");break;}}while(choice!=0);printf("谢谢使用!\n");return 0;}四实验小结初步了解线性表的顺序存储结构,及其定义格式。
掌握在顺序表上进行插入、删除等操作的算法。
但在顺序表的操作上不是十分熟练。
五成绩实验二实验名称单链表及其应用实验性质综合性实验学时数4学时四实验小结初步了解线性表的链式存储结构,及其定义格式。
掌握了在链表上进行插入、删除等操作的算法。
对链表的了解不是很深入,在其使用上往往会犯一些错误比如在链表中进行插入插不到指定位置,删除时位置错误等。
五成绩实验三实验名称线性表综合练习实验性质设计性实验学时数6学时四实验小结对链式表有了进一步的了解,能够利用链式表解决一些实际问题。
了解了链式表的优势,他不会造成空间的浪费,对于插入和删除操作上链式表比顺序表有明显的优势。
五成绩实验四实验名称栈和队列及其应用实验性质设计性实验学时数4学时四实验总结对栈和队列有了初步的了解,他们都是一种特殊的操作受限制线性表,栈的特点是先进后出而队列的是先进先出。
数据结构入门-树的遍历以及二叉树的创建

数据结构⼊门-树的遍历以及⼆叉树的创建树定义:1. 有且只有⼀个称为根的节点2. 有若⼲个互不相交的⼦树,这些⼦树本⾝也是⼀个树通俗的讲:1. 树是有结点和边组成,2. 每个结点只有⼀个⽗结点,但可以有多个⼦节点3. 但有⼀个节点例外,该节点没有⽗结点,称为根节点⼀、专业术语结点、⽗结点、⼦结点、根结点深度:从根节点到最底层结点的层数称为深度,根节点第⼀层叶⼦结点:没有⼦结点的结点⾮终端节点:实际上是⾮叶⼦结点度:⼦结点的个数成为度⼆、树的分类⼀般树:任意⼀个结点的⼦结点的个数都不受限制⼆叉树:任意⼀个结点的⼦结点个数最多是两个,且⼦结点的位置不可更改⼆叉数分类:1. ⼀般⼆叉数2. 满⼆叉树:在不增加树层数的前提下,⽆法再多添加⼀个结点的⼆叉树3. 完全⼆叉树:如果只是删除了满⼆叉树最底层最右边的连续若⼲个结点,这样形成的⼆叉树就是完全⼆叉树森林:n个互不相交的树的集合三、树的存储⼆叉树存储连续存储(完全⼆叉树)优点:查找某个结点的⽗结点和⼦结点(也包括判断有没有⼦结点)速度很快缺点:耗⽤内存空间过⼤链式存储⼀般树存储1. 双亲表⽰法:求⽗结点⽅便2. 孩⼦表⽰法:求⼦结点⽅便3. 双亲孩⼦表⽰法:求⽗结点和⼦结点都很⽅便4. ⼆叉树表⽰法:把⼀个⼀般树转化成⼀个⼆叉树来存储,具体转换⽅法:设法保证任意⼀个结点的左指针域指向它的第⼀个孩⼦,右指针域指向它的兄弟,只要能满⾜此条件,就可以把⼀个⼀般树转化为⼆叉树⼀个普通树转换成的⼆叉树⼀定没有右⼦树森林的存储先把森林转化为⼆叉树,再存储⼆叉树四、树的遍历先序遍历:根左右先访问根结点,再先序访问左⼦树,再先序访问右⼦树中序遍历:左根右中序遍历左⼦树,再访问根结点,再中序遍历右⼦树后续遍历:左右根后续遍历左⼦树,后续遍历右⼦树,再访问根节点五、已知两种遍历求原始⼆叉树给定了⼆叉树的任何⼀种遍历序列,都⽆法唯⼀确定相应的⼆叉树,但是如果知道了⼆叉树的中序遍历序列和任意的另⼀种遍历序列,就可以唯⼀地确定⼆叉树已知先序和中序求后序先序:ABCDEFGH中序:BDCEAFHG求后序:这个⾃⼰画个图体会⼀下就可以了,⾮常简单,这⾥简单记录⼀下1. ⾸先根据先序确定根,上⾯的A就是根2. 中序确定左右,A左边就是左树(BDCE),A右边就是右树(FHG)3. 再根据先序,A左下⾯就是B,然后根据中序,B左边没有,右边是DCE4. 再根据先序,B右下是C,根据中序,c左下边是D,右下边是E,所以整个左树就确定了5. 右树,根据先序,A右下是F,然后根据中序,F的左下没有,右下是HG,6. 根据先序,F右下为G,然后根据中序,H在G的左边,所以G的左下边是H再来⼀个例⼦,和上⾯的思路是⼀样的,这⾥就不详细的写了先序:ABDGHCEFI中序:GDHBAECIF已知中序和后序求先序中序:BDCEAFHG后序:DECBHGFA这个和上⾯的思路是⼀样的,只不过是反过来找,后序找根,中序找左右树简单应⽤树是数据库中数据组织⼀种重要形式操作系统⼦⽗进程的关系本⾝就是⼀棵树⾯向对象语⾔中类的继承关系哈夫曼树六、⼆叉树的创建#include <stdio.h>#include <stdlib.h>typedef struct Node{char data;struct Node * lchild;struct Node * rchild;}BTNode;/*⼆叉树建⽴*/void BuildBT(BTNode ** tree){char ch;scanf("%c" , &ch); // 输⼊数据if(ch == '#') // 如果这个节点的数据是#说明这个结点为空*tree = NULL;else{*tree = (BTNode*)malloc(sizeof(BTNode));//申请⼀个结点的内存 (*tree)->data = ch; // 将数据写⼊到结点⾥⾯BuildBT(&(*tree)->lchild); // 递归建⽴左⼦树BuildBT(&(*tree)->rchild); // 递归建⽴右⼦树}}/*⼆叉树销毁*/void DestroyBT(BTNode *tree) // 传⼊根结点{if(tree != NULL){DestroyBT(tree->lchild);DestroyBT(tree->rchild);free(tree); // 释放内存空间}}/*⼆叉树的先序遍历*/void Preorder(BTNode * node){if(node == NULL)return;else{printf("%c ",node->data );Preorder(node->lchild);Preorder(node->rchild);}}/*⼆叉树的中序遍历*/void Inorder(BTNode * node){if(node == NULL)return;else{Inorder(node->lchild);printf("%c ",node->data );Inorder(node->rchild);}}/*⼆叉树的后序遍历*/void Postorder(BTNode * node){if(node == NULL)return;else{Postorder(node->lchild);Postorder(node->rchild);printf("%c ",node->data );}}/*⼆叉树的⾼度树的⾼度 = max(左⼦树⾼度,右⼦树⾼度) +1*/int getHeight(BTNode *node){int Height = 0;if (node == NULL)return 0;else{int L_height = getHeight(node->lchild);int R_height = getHeight(node->rchild);Height = L_height >= R_height ? L_height +1 : R_height +1; }return Height;}int main(int argc, char const *argv[]){BTNode * BTree; // 定义⼀个⼆叉树printf("请输⼊⼀颗⼆叉树先序序列以#表⽰空结点:");BuildBT(&BTree);printf("先序序列:");Preorder(BTree);printf("\n中序序列:");Inorder(BTree);printf("\n后序序列:");Postorder(BTree);printf("\n树的⾼度为:%d" , getHeight(BTree));return 0;}// ABC##DE##F##G##。
数据结构课程设计二 叉 树 遍 历 及 应 用

实验报告课程:数据结构课程设计设计题目:二叉树遍历及应用学号:班级:软件11k1姓名: 南方小羊指导教师:刘军二叉树的遍历1、问题描述利用先序遍历建立一棵二叉树,并分别用前序、中序、后序遍历该二叉树2、节点形式Lchild data Rchild3、说明(1)输入数据:1,2,3,0,0,4,0,0,5,0,0其中“0”表示空子树。
(2)输出数据:先序:1,2,3,4,5中序:3,2,4,1,5后序:3,4,2,5,1二叉树的应用1、问题描述运用二叉树的遍历的算法,编写算法分别实现如下功能。
(1)求出二叉树中的结点的总数。
(2)求出二叉树中的叶子数目。
(3)求出二叉树的深度。
运用上题所建立的二叉树,求出其结点总数、叶子数目、深度,最后释放所有结点。
二叉树结点结构中包数据域(data),指针域(*lchild,*rchild)。
结点结构的代码如下:typedef struct tree{int data;struct tree *lchild,*rchild;}*bitree;本实例使用的是二叉树,首先建立头结点,并且保存数据,然后根据递归方法,分别建立其左右孩子结点,且左右孩子结点的指针域指向空。
先序递归遍历时,输出第一个根结点数据,然后分别遍历左子树再遍历右子树,中序遍历,先访问根结点的左子树输出数据,再输出根结点的数据,再访问右子树,后序遍历先访问根结点的右子树,再访问根结点,再访问左子树输出。
统计二叉树叶子的个数可以看成一个遍历问题,访问一个结点,判断该结点是否为叶子,如果是将叶子树加1,可以采用任何遍历实现,求二叉树的深度是假设根结点为第一层的结点,所有K层结点的左右孩子在K+1层,所以可以通过先序遍历计算二叉树中每个结点的层数,其中最大的就是二叉树的深度。
四、实验心得:树结构是数据结构课程的典型内容,而且综合使用了多种逻辑结构,具有代表性,可以锻炼个人编程能力。
在刚开始选题后,我感觉无从下手,一是因为没有实践经验,二是因为对数据结构课程的内容没有把握到位,然后在参考一些专业书籍并且学习了之前其他人的课程设计,才逐渐可以上手去自己做。
数据结构_二叉树的遍历_课程设计

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. 二叉树的创建和初始化:我们将实现二叉树的创建和初始化操作,以便后续操作和测试使用。
3. 二叉树的遍历:我们将实现二叉树的前序、中序和后序遍历算法,并测试其正确性和效率。
4. 二叉树的查找:我们将实现二叉树的查找操作,包括查找节点和查找最大值、最小值等。
5. 二叉树的应用:我们将探讨二叉树在实际应用中的使用场景,如哈夫曼编码、二叉搜索树等。
二叉树的定义和存储结构二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。
节点被表示为一个由数据和指向其左右子节点的指针组成的结构。
二叉树可以分为三类:满二叉树、完全二叉树和非完全二叉树。
二叉树可以用链式存储结构或顺序存储结构表示。
- 链式存储结构:采用节点定义和指针表示法,通过将节点起来形成一个树状结构来表示二叉树。
- 顺序存储结构:采用数组存储节点信息,通过计算节点在数组中的位置来进行访问和操作。
二叉树的创建和初始化二叉树的创建和初始化是二叉树操作中的基础部分。
我们可以通过手动输入或读取外部文件中的数据来创建二叉树。
对于链式存储结构,我们需要自定义节点和指针,并通过节点的方式来构建二叉树。
对于顺序存储结构,我们需要定义数组和索引,通过索引计算来定位节点的位置。
一般来说,初始化一个二叉树可以使用以下步骤:1. 创建树根节点,并赋初值。
2. 创建子节点,并到父节点。
3. 重复步骤2,直到创建完整个二叉树。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
建立二叉树-并对树进行操作数据结构课程设课题名:建立二叉树,并对树进行操作系别:信息与计算科学系年级:2009级专业:数学与应用数学班级:一班学号:2009031116、2009031112、2009123123、2009031102、2009031110姓名:唐永桥、杨文升、李兵、陈丕权、范庆勇指导老师:李学勇2011-5-10目录摘要 ........................................................................................... 错误!未定义书签。
1、引言 ......................................................................................... 错误!未定义书签。
1.1设计目标 (5)1.2 相关知识 (5)2、总体设计 (10)2.1主要数据存储结构设计 (10)2.2模块的划分及其功能 (10)3、详细设计 (11)3.1存储结构的建立由scanf()函数实现 (11)3.2重要函数 (12)3.3程序相关分析 (12)3.4结构体和全局变量定义 (12)3.5程序清单 (13)4、测试数据及结果分析 (19)5、总结 ......................................................................................... 错误!未定义书签。
6、参考文献 (22)[1]《数据结构》(C语言版),严蔚敏,清华大学出版社,2003. (22)1、运行环境、开发工具运行环境:VC++ 6.0开发工具:电脑2、需求分析2.1设计目标二叉树是形象的说既树中每个节点最多只有两个分支,它是一个重要的数据类型。
可以运用于建立家谱,公司所有的员工的职位图,以及各种事物的分类和各种机构的职位图表。
二叉树是通过建立一个链式存储结构,达到能够实现前序遍历,中序遍历,后序遍历。
以及能够从输入的数据中得知二叉树的叶子节点的个数,二叉树的深度。
在此,二叉树的每一个结点中必须包括:值域,左指针域,右指针域。
2.2 相关知识1、status CreateBiTree(BiTree *T){// 先序创建二叉树TelemType ch;scanf("%c",&ch);if(ch==ENDFLAG) *T=NULL;else {if(!(*T=(BiTNode *)malloc(sizeof(BiTNode)))){printf("\nOut of space.");getch();exit(0);}(*T)->data=ch; //生成根结点CreateBiTree(&((*T)->lchild));//左子树CreateBiTree(&((*T)->rchild));//右子树}return OK;}TelemType的作用是输入n各任意的字符,而且在输入n个字符后,必须输入N=1个0,才能够得到本程序所有能够实现的功能。
T=Null是将二叉树置为空。
if(!(*T=(BiTNode *)malloc(sizeof(BiTNode))))//采用动态申请结点的方式,不仅实现起来方便,而且还节省大量的存储空间。
(*T)->data=ch; //生成根结点CreateBiTree(&((*T)->lchild));//左子树CreateBiTree(&((*T)->rchild));//右子树2、前序遍历:先访问根结点,再访问左子树,最后访问右子树。
具体实现如下:status PreOrderTraverse(BiTree T){if(T){printf("%c",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}return OK;}3、求叶子结点的个数:用m变量表示叶子结点的总个数。
当树为空是此时讨论叶子结点个数无意义;当树非空时分为:一、左右子树都不存在时,m自加1,m的值就为1,即叶子结点的个数为1;二、左右子树存在,就用分别访问出左右子树中叶子结点的个数,两者相加就为二叉树叶子结点的个数。
具体实现如下://求二叉树的叶结点个数status NumberLeaves(BiTree T){//先序遍历得到叶结点的数目//m=0;if(T){if(T->lchild==NULL&&T->rchild==NULL) m++;NumberLeaves(T->lchild);NumberLeaves(T->rchild);}return OK;}4、中序遍历:先访问左子树,再访问根结点,最后访问右子树。
具体实现如下:status InOrderTraverse(BiTree T){if(T){InOrderTraverse(T->lchild);printf("%c",T->data);InOrderTraverse(T->rchild);}return OK;}5、后序遍历:先访问左子树,再访问右子树,最后访问根结点。
具体实现如下:status PostOrderTraverse(BiTree T){if(T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%c",T->data);}return OK;}6、求二叉树的深度:先定义2个整形变量m,n,并将其初值设为0。
如果树为空,则深度0;否则,先分别访问出左右子树的深度,再进行比较,将较大的+1的结果就是所求二叉树的深度。
具体实现如下:status Max(int m, int n) //一个比较函数{if (m > n)return m;elsereturn n;}//获取二叉树的高度status HighBitree(BiTree t){if (t == NULL)return 0;elsereturn 1 + Max(HighBitree(t->lchild), HighBitree(t->rchild));}5、主函数包括:BiTree T,reateBiTree(&T),NumberLeaves(T),printf("%d",HighBitree(T)),PreOrderTraverse(T),InOrderTraverse(T),PostOrderTraverse(T),ArrangementTraverse(T)//主函数void main(){BiTree T;printf("请创建二叉树:\n");CreateBiTree(&T);NumberLeaves(T);printf("叶节点个数为:");printf("%d",m);printf("\n二叉树的高度为:");printf("%d",HighBitree(T));printf("\n先序遍历:\n");PreOrderTraverse(T);/* printf("\n中序遍历:\n");InOrderTraverse(T);printf("\n后序遍历:\n"); PostOrderTraverse(T);*/ printf("\n层次遍历\n"); ArrangementTraverse(T); printf("\n");}2程序设计2.1主要数据存储结构设计本设计中,对二叉树采用链式存储结构,其结构定义如下:typedef struct BiTNode{TelemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;每个结点中设置三个域,即值域data,左指针域*lchild和右指针域*child。
2.2模块的划分及其功能本程序分为:6大模块。
二叉树的建立链式存储结构,前序遍历,求叶子结点的个数计算,中序遍历,后序遍历,深度求解。
1)二叉树的建立:定义二叉树的链式存储结构,输入数据生成二叉树。
二叉树的前序遍历:利用二叉链表作为存储结构的前序遍历;先访问根结点,再依次访问左右子树。
2)二叉树的求叶子结点的个数计算:先分别求的左右子树中各叶子结点的个数,再计算出两者之和即为二叉树的叶子结点数。
3)二叉树的中序遍历:利用二叉链表作为存储结构的中序遍历;先访问左子树,再访问根结点,最后访问右子树。
4)二叉树的后序遍历:利用二叉链表作为存储结构的前序遍历;先访问左右子树,再访问根结点5)求二叉树的深度:首先判断二叉树是否为空,若为空则此二叉树的深度为0.否则,就先求出左右子树的深度并进行比较,求较大的+1就为二叉树的深度。
6)主函数。
核心算法的设计:二叉树是n各结点的有穷个集合,它或者是空集(n=0),或者同时满足以下两个条件:(1):有且仅有一个称为根的节点:(2):其余节点分为两个互为相交的集合T1,T2,并且T1,T2都是二叉树,分别称为根的左子树和右子树。
3.1存储结构的建立由scanf ()函数实现一、首先输入的是根结点;二、然后输入的是根结点的左孩子;三、再者输入的是根结点的右孩子;四、接着输入的是根结点左孩子的左孩子;五、输入的是根结点的左孩子的;六、输入的是根结点的右孩子的左孩子;七、输入的是根结点的右孩子的左孩子;建中求先后求 主开八、最后输入的是根结点的右孩子的右孩子。
依次输入数据。
3.2重要函数主函数 void main()输入函数 printf()输出函数 scanf()二叉树的先序建立函数 CreateBiTree()二叉树的先序遍历函数 PreOrderTraverse()二叉树的中序遍历函数 InOrderTraverse()二叉树的后序遍历函数 PostOrderTraverse()二叉树的层序遍历函数 ArrangementTraverse()求叶子节点函数 NumberLeaves()求深度函数 HighBitree()比较函数 Max()3.3程序相关分析#include <stdio.h> /*标准输入输出函数定义*/#include <string.h> /*字符和字符串函数定义*/#include <conio.h> /*控制台进行数据输入和数据输出的函数*/#include <stdlib.h> /*常见数学函数定义*/(本程序中涉及很多关于字符串的函数,使用其函数,必须先定义)3.4结构体和全局变量定义#define OK 1#define ERROR -1#define ENDFLAG '#'/*表示节点没有左孩子或者没有右孩子用#代替*/ typedef char TelemType;/*宏定义char类型*/typedef int status;/*宏定义int类型*/typedef struct BiTNode{TelemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree; /*二叉树的存储结构*/int m=0; /*全局变量,表示叶子个数*/3.5程序清单//头文件#include "stdio.h"#include "conio.h"#include "stdlib.h"//预定义宏常量#define OK 1#define ERROR -1#define ENDFLAG '#'typedef char TelemType;typedef int status;//二叉树的存储结构typedef struct BiTNode{TelemType data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;//全局变量,表示叶子个数int m=0;//二叉树的创建status CreateBiTree(BiTree *T){// 先序创建TelemType ch;scanf("%c",&ch);if(ch==ENDFLAG) *T=NULL;else{if(!(*T=(BiTNode *)malloc(sizeof(BiTNode)))) {printf("\nOut of space.");getch();exit(0);}(*T)->data=ch; //生成根结点CreateBiTree(&((*T)->lchild));//左子树CreateBiTree(&((*T)->rchild));//右子树 }return OK;}//先序遍历status PreOrderTraverse(BiTree T){if(T){printf("%c",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}return OK;}/*//中序status InOrderTraverse(BiTree T){if(T){InOrderTraverse(T->lchild);printf("%c",T->data);InOrderTraverse(T->rchild);}return OK;}//后序status PostOrderTraverse(BiTree T){if(T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%c",T->data);}return OK;}*//*用队列层次遍历*///存储定义typedef char QElemType;//typedef int status;typedef struct Queue{QElemType data;struct Queue *next;}Queue;//头指针和尾指针typedef struct{Queue *front;Queue *rear;}LinkQueue;//初始化队列status InitQueue(LinkQueue *q){q->front=q->rear =NULL; //----无头结点return OK;}/*判断队列是否为空*/status QueueEmpty(LinkQueue *Q){return (Q->front==NULL)&&(Q->rear==NULL);/*实际上只须判断队头指针是否为空即可*/}//入队void EnQueue(LinkQueue *q,QElemType e){Queue *p;p=(Queue *)malloc(sizeof(Queue));/*申请新结点*/ p->data=e;p->next=NULL;if(QueueEmpty(q))q->front=q->rear=p;else{/*x插入非空队列的尾*/q->rear->next=p; /*p链到原队尾结点后*/q->rear=p;/*队尾指针指向新的尾*/}}//出队QElemType DeQueue(LinkQueue *q){Queue *p;QElemType e;if(QueueEmpty(q)){printf("Queue underflow\n");/*下溢*/exit(1) ;}p=q->front;/*指向对头结点*/e=p->data;/*保存对头结点的数据*/q->front=p->next;/*将对头结点从链上摘下*/if(q->rear==p)/*原队中只有一个结点,删去后队列变空,此时队头指针已为空*/q->rear=NULL;free(p);/*释放被删队头结点*/return e;/*返回原队头数据*/}/*层次遍历思想递归a.根结点入队列b.原队左子树的左右孩子(非空)入队列c.原队右子数的左右孩子(非空)入队列*///层次遍历入队列status Arrange(BiTree T,LinkQueue *Q){if(T){EnQueue(Q,T->data);Arrange(T->lchild,Q);Arrange(T->rchild,Q);}return OK;}//从队列中输出各元素status ArrangementTraverse(BiTree T){char e;LinkQueue Q;InitQueue(&Q);if(T){Arrange(T,&Q);//递归调用while(!QueueEmpty(&Q)){e=DeQueue(&Q);printf("%c",e);}}return OK;}//求二叉树的叶结点个数status NumberLeaves(BiTree T){//先序遍历得到叶结点的数目//m=0;if(T){if(T->lchild==NULL&&T->rchild==NULL) m++;NumberLeaves(T->lchild);NumberLeaves(T->rchild);}return OK;}//一个比较函数status Max(int m, int n){if (m > n)return m;elsereturn n;}//获取二叉树的高度status HighBitree(BiTree t){if (t == NULL)return 0;elsereturn 1 + Max(HighBitree(t->lchild), HighBitree(t->rchild));}//主函数void main(){BiTree T;printf("请创建二叉树:\n");CreateBiTree(&T);NumberLeaves(T);printf("叶节点个数为:");printf("%d",m);printf("\n二叉树的高度为:");printf("%d",HighBitree(T)); printf("\n先序遍历:\n");PreOrderTraverse(T);/* printf("\n中序遍历:\n"); InOrderTraverse(T);printf("\n后序遍历:\n");PostOrderTraverse(T);*/printf("\n层次遍历\n");ArrangementTraverse(T);printf("\n");}4、测试数据及结果分析(1) (2)输入ABD##E##CF###结果为:叶子点个数为:3二叉树的高度为:3先序遍历:ABDECF层序遍历:ABDECF输入:ABE#F#G##H#I##C#D###叶子点个数为:3A C DB F E AB C H G F E I D二叉树的高度为:5 先序遍历:ABEFGHICD 层序遍历:ABEFGHICD结束语通过二叉树的创建,及和同学各方面的研究和讨论,我才深深的意识到我学习方面的不足,这次设计不仅更深的了解到二叉树的含义,也让我发现和同学合作一起做设计,能极大的提高自己对学习方面的兴趣,让我意识到,在大学里,我要用有限的时间学到更多东西。