实验3 二叉树及其应用
实习三 二叉树及其应用
![实习三 二叉树及其应用](https://img.taocdn.com/s3/m/73d01ef2f242336c1fb95e7c.png)
实习三树、二叉树及其应用题目:唯一地确定一棵二叉树实习时间:2012/10/30一、需求分析1.问题描述:如果给出了遍历二叉树的前序序列和中序序列,则可以构造出唯一的一棵二叉树。
试编写实现上述功能的程序。
2.基本要求: 已知一棵二叉树的前序和中序序列,试设计完成下列任务的一个算法:(1)构造一棵二叉树;(2)证明构造正确(即分别以前序和中序遍历该树,将得到的结果与给出的序列进行比较)。
3.测试数据: 前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。
二、设计二、 1. 设计思想二、(1)存储结构二、用两个一维数组A和B分别存放前序和中序序列。
(2)主要算法基本思想①将前序和中序序列分别读入数组A和B。
②根据定义,前序序列中第一个元素一定是树根,在中序序列中该元素之前的所有元素一定在左子树中,其余元素则在右子树中。
所以,首先从数组A中取出第一个元素A[0]作根结点,然后在数组B中找到A[0],以它为界,在其前面的是左子树中序序列,在其后面的是右子树中序序列。
③若左子树不为空,沿前序序列向后移动,找到左子树根结点,转②。
④左子树构造完毕后,若右子树不为空,沿前序序列向后移动,找到右子树根结点,转②。
⑤前序序列中各元素取完则二叉树构造完毕。
⑥对二叉树进行前序和中序遍历,并将结果分别与数组A和B进行比较,若相同,则证明二叉树构造正确。
2. 设计表示(1)函数调用关系图main→StackPush→QueueAppend→QueueAd→StackPop→QueueGet(2)函数接口规格说明void PrintTree(BiTreeNode root,int n) //以root为根节点的树凹形输出void Initiate(BiTreeNode *root) // 以root为根节点的树初始化void PreOrder(BiTreeNode bt) //前序遍历以bt为根结点指针的二叉树void InOrder(BiTreeNode bt) //中序遍历以bt为根结点指针的二叉树int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T) //用前序序列和中序序列构造以T 为根节点的树,其中pre,in分别为前序序列和中序序列的首地址,al为中序序列的长度。
实验三 二叉树
![实验三 二叉树](https://img.taocdn.com/s3/m/d49dee09a76e58fafab00379.png)
实验三二叉树
一、实验目的
1.掌握二叉树的链式存储结构及其相关操作的实现。
2.掌握二叉树的先序、中序、后序的递归遍历算法。
3.理解二叉树的各种非递归遍历算法的实现。
二、实验要求
1.实验前做好充分准备,包括复习第六章所学内容,事先预习好本次实验内容。
2.实验时记录实验结果,按要求完成各题。
3.实验结束后,给出实验总结与分析并及时给出本次实验的实验报告。
三、实验题目
本次实验给出的选定题目如下表所示。
说明:
(1)实验内容1)为必做内容。
(2)实验内容2)与实验内容3)为选做内容。
四、实验内容与要求
1、实验题目一:(1)二叉树的创建、递归遍历及其它基本操作的实现。
要求:定义用二叉链表表示的二叉树,并实现二叉树的创建、遍历(先序、中序后序)的递归算法及求深度操作等,并对其进行验证。
2、实验题目二:二叉树非递归遍历算法的实现
要求:在题目一的基础上,实现二叉树的非递归遍历算法(先序、中序、后序或按层),并对其进行验证。
3、实验题目三:哈夫曼树及哈夫曼编码的算法实现
要求:编程实现哈夫曼树的创建及利用哈夫曼树求解哈夫曼编码。
实验三二叉树基本操作与应用实验
![实验三二叉树基本操作与应用实验](https://img.taocdn.com/s3/m/887f2af309a1284ac850ad02de80d4d8d15a018c.png)
实验三二叉树基本操作与应用实验第一篇:实验三二叉树基本操作与应用实验实验三二叉树基本操作与应用实验第三次实验主要包括两部分内容:1.二叉树基本操作实验;2.二叉树应用—赫夫曼树与赫夫曼编码实验。
基本操作包括存储结构建立和遍历算法,本文只给出部分参考程序,请大家尽量完成多数基本操作。
第一部分基本操作实验[问题描述] 二叉树采用二叉链表作存储结构,试编程实现二叉树的如下基本操作1.按先序序列构造一棵二叉链表表示的二叉树T;2.对这棵二叉树进行遍历:先序、中序、后序以及层次遍历序列,分别输出结点的遍历序列;3.求二叉树的深度,结点数目,叶结点数目; [数据描述] //二叉树的二叉链表存储表示先序遍历二叉树递归算法6.层次遍历二叉树的非递归算法7.求二叉树的深度[说明]1.按先序次序输入二叉树中结点的值,用‘#’表示空树,对每一个结点应当确定其左右子树的值(为空时必须用特定的空字符占位),故执行此程序时,最好先在纸上画出你想建立的二叉树,每个结点的左右子树必须确定。
若为空,则用特定字符标出,然后再按先序输入这棵二叉树的字符序列。
2.为了简化程序的书写量,以及程序的清晰性,对结点的访问以一条输出语句表示,若有更复杂的或多种访问,可以将结点的访问编写成函数,然后通过函数指针进行函数的调用。
读者若有兴趣,可自行编写。
3.c语言函数参数传递,都是以“传值”的方式,故在设计函数时,必须注意参数的传递。
若想通过函数修改实际参数的值,则必须用指针变量作参数。
具体设计时;读者一定要把指针变量及指针变量指向的值等概念弄清楚。
4.完整参考程序只给出了部分遍历算法,对于其他算法,请读者参照示例,自行编程完成,以加深学习体会。
对于二叉链表的建立也是如此,示例中只是给出了先序法建立过程,读者可自行练习中序、后序二叉链表建立法,叶子结点或二叉树结点总数求法等。
第二部分二叉树应用实验---------郝夫曼树与郝夫曼编码[问题描述] 利用HuffMan编码进行通信可以大大提高信道利用率,缩短信息传输时间,降低传输成本。
实验三 二叉树的操作及应用
![实验三 二叉树的操作及应用](https://img.taocdn.com/s3/m/6295e91dbb68a98271fefa84.png)
实验三二叉树的操作及应用实验课程名:数据结构与算法专业班级:15计科1班学号:201540410109 姓名:刘江实验时间:2016.10.24-10.31 实验地点:K4-102 指导教师:冯珊成绩:一、实验目的及要求1、进一步掌握指针变量、动态变量的含义。
2、掌握二叉树的结构特性,以及各种存储结构的特点和适用范围。
3、掌握用指针类型描述、访问和处理二叉树的运算。
二、实验内容任务一:完成下列程序,该程序以二叉链表作存储结构,构建如图1所示的二叉树,并依次进行二叉树的前序、中序、后序及层次遍历。
图1解答:(1)源代码:#include<stdio.h>#include<stdlib.h>#define OK 1#define ERROR 0typedef char DataType;/* 二叉树节点的存储类型 */typedef struct Node //define stricture BiTree{ DataType data;struct Node *lchild,*rchild;}Node, *BiTree;/*按先序序列建立一棵二叉树*/BiTree CreatBiTree(BiTree &T){DataType ch;scanf("%c",&ch);if(ch==' ') {T=NULL;}else{if(!(T=(Node*)malloc(sizeof(Node)))){printf("Overflow.\n") ;exit(0);}T->data =ch;CreatBiTree(T->lchild );CreatBiTree(T->rchild );}return T;}void PrintData(DataType x){printf("%c",x);}void PreOrder(BiTree T, void (*Visit)( DataType item))/*前序遍历二叉树T,访问操作为Visit()函数*/{if(T!= NULL){Visit(T->data);PreOrder(T->lchild, Visit);PreOrder(T->rchild, Visit);}}void InOrder(BiTree T, void (*Visit)( DataType item)) /*中序t */ {if(T!= NULL){InOrder(T->lchild, Visit);Visit(T->data);InOrder(T->rchild, Visit);}}void PostOrder(BiTree T, void (*Visit)( DataType item)) /*后序 */ {if(T!= NULL){PostOrder(T->lchild, Visit);PostOrder(T->rchild, Visit);Visit(T->data);}}int main(){int choice;BiTree root;printf("下面建立一棵二叉树,结点数据输入按先序次序。
实验三二叉树及其应用(2次上机)
![实验三二叉树及其应用(2次上机)](https://img.taocdn.com/s3/m/66a9c05f27284b73f24250a7.png)
实验三 二叉树及其应用(2次上机)【上机时间】第5~7次【实验目的】树是一种应用极为广泛的数据结构之一,是本课程的重点。
树是一种1:N 的非线性结构。
本章首先以二叉树这种特殊、简单的树为原型,讨论数据元素(结点)之间的1:N(N=0,1,2)关系的表示(顺序映像——完全二叉树的顺序存储;链式映像——二叉链表、三叉链表);重点介绍二叉树的各种遍历算法(先序、中序、后序、层次遍历);并以这些遍历算法为基础,进一步讨论二叉树的其他各种问题的求解算法。
然后,展开对一般树的表示(双亲表示法、孩子表示法、孩子-兄弟表示法)和操作算法的讨论;强调树(森林)的孩子-兄弟表示法及其相关应用;并将表示树(森林)的孩子-兄弟链映射到表示二叉树的二叉链,从而获得树(森林)与二叉树的相互转换。
本实验以二叉树的链式表示、建立和应用为基础,旨在让学生深入了解二叉树的存储表示特征以及遍历次序与二叉树的存储结构之间的关系,进一步掌握利用遍历思想解决二叉树中相关问题的方法。
本实验的另一个目的是让学生通过思考、上机实践与分析总结,理解计算机进行算术表达式解析、计算的可能方法,初步涉及一些编译技术,增加自己今后学习编译原理的兴趣,并奠定一些学习的基础。
【实验内容】本实验由以下环节组成:1) 存储结构以二叉链表或三叉链表作为二叉树的存储结构;2) 二叉树的创建(链式存储)以某一种遍历的次序录入二叉树的元素,写出相应的二/三叉链表的创建算法,并上机实现该算法;二叉树的输入次序可以有如下几种方法,你可以选择其中之一来作为二/三叉链表创建程序的输入:(1) 添加虚结点补足成完全二叉树,对补足虚结点后的二叉树按层次遍历次序输入。
如图1的二叉树输入次序为:A, B, C, Φ, D, E, F, Φ, Φ, G , Φ, Φ, H也可以通过添加虚结点,为每一实在结点补足其孩子,再对补足虚结点后的二叉树按层次遍历的次序输入。
如图1的二叉树输入次序为:A, B, C, Φ, D, E, F, G , Φ, Φ, H , Φ, Φ, Φ, Φ, Φ, Φ进一步改进,可以在输入列表中忽略出现在列表尾部的虚结点,即:A, B, C, Φ, D, E, F, G , Φ, Φ, H(2) 通过添加虚结点,将二叉树中的每一实在结点补足成度为2的结点,对补足虚图 1结点后的二叉树按先序遍历的次序输入。
数据结构实验3:二叉树的操作
![数据结构实验3:二叉树的操作](https://img.taocdn.com/s3/m/39a5645d6ad97f192279168884868762caaebba2.png)
TextFile中。
(4) P:打印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrin中。
(5) T:打印哈夫曼树(Tree printing)。
将已在内存中的哈夫曼树以直观的方式显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
3) 实现提示:(1) 文件CodeFile的基类型可以设为字节型。
(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。
请用户键入一个选择功能符。
此功能执行完毕后再显示此菜单,直至某次用户选择了“E”为止。
(3) 在程序的一次执行过程中,第一次执行I、D或C命令之后,哈夫曼树已经在内存了,不必再读入。
每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。
三、实验过程与实验结果实验3-01:以二叉链表为存储结构,实现二叉树的创建、遍历数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。
2.利用非递归实现中序遍历,需要利用栈操作,按照中序遍历规则将节点依次入栈后出栈实现。
算法描述:图1 中序遍历(非递归)实现算法的实现和测试结果(参考OJ)实验3-02:编写算法交换二叉树中所有结点的左、右子树数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。
二叉树 实验报告
![二叉树 实验报告](https://img.taocdn.com/s3/m/a637d91d814d2b160b4e767f5acfa1c7aa008233.png)
二叉树实验报告二叉树实验报告引言:二叉树是一种常见的数据结构,它由节点和边组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。
在本次实验中,我们将探索二叉树的基本概念、特性以及应用。
一、二叉树的定义与性质1.1 二叉树的定义二叉树是一种递归定义的数据结构,它可以为空,或者由一个根节点和两个二叉树组成,分别称为左子树和右子树。
1.2 二叉树的性质(1)每个节点最多有两个子节点,分别称为左子节点和右子节点。
(2)左子树和右子树也是二叉树。
(3)二叉树的子树之间没有关联性,它们是相互独立的。
二、二叉树的遍历方式2.1 前序遍历前序遍历是指先访问根节点,然后按照先左后右的顺序遍历左子树和右子树。
2.2 中序遍历中序遍历是指先遍历左子树,然后访问根节点,最后遍历右子树。
2.3 后序遍历后序遍历是指先遍历左子树,然后遍历右子树,最后访问根节点。
2.4 层次遍历层次遍历是指按照从上到下、从左到右的顺序遍历二叉树的每个节点。
三、二叉树的应用3.1 二叉搜索树二叉搜索树是一种特殊的二叉树,它的每个节点的值大于其左子树的所有节点的值,小于其右子树的所有节点的值。
这种特性使得二叉搜索树可以高效地进行查找、插入和删除操作。
3.2 哈夫曼树哈夫曼树是一种带权路径长度最短的二叉树,它常用于数据压缩中。
哈夫曼树的构建过程是通过贪心算法,将权值较小的节点放在离根节点较远的位置,从而实现最优编码。
3.3 表达式树表达式树是一种用于表示数学表达式的二叉树,它的叶节点是操作数,而非叶节点是操作符。
通过对表达式树的遍历,可以实现对表达式的求值。
结论:通过本次实验,我们对二叉树的定义、性质、遍历方式以及应用有了更深入的了解。
二叉树作为一种重要的数据结构,在计算机科学和算法设计中发挥着重要的作用。
在今后的学习和工作中,我们应该进一步探索二叉树的高级应用,并灵活运用于实际问题的解决中。
实验3 二叉树的操作及应用
![实验3 二叉树的操作及应用](https://img.taocdn.com/s3/m/6c46126fddccda38376baf71.png)
实验3 二叉树的操作及应用PB13000818 焦孟娇实验目的:1. 熟练掌握递归程序设计的方法。
2. 掌握二叉树的特性和基本算法。
问题描述:二叉树是一种基本且常用的数据结构。
二叉树的很多基本算法都可以用递归的形式来表述。
本实验要求实现二叉树的如下操作:创建、销毁、复制、打印显示、先中后序遍历、查找元素、层序遍历、求二叉树的深度、宽度、结点数和叶子个数等。
实验内容:一、队列的抽象数据类型定义为:Queue operation{数据对象:数据关系:基本操作:InitQueue(&S)操作结果:构造一个空队列SQueueLength(S)初始条件:队列S已存在操作结果:返回S的元素个数,即队列的长度QueueEmpty(S)初始条件:队列S已存在操作结果:若S为空队列,则返回TRUE,否则FALSEEnQueue(&S, e)初始条件:队列S已存在操作结果:插入元素e为队列新元素DeQueue(&S, &e)初始条件:队列S已存在且非空操作结果:删除S的队头元素,并用e返回其值GetHead(S, &e)初始条件:队列S已存在且非空操作结果:用e返回S的队头元素ClearQueue(&S)初始条件:队列S已存在操作结果:将S清为空队列DeleteQueue(&S)初始条件:队列S已存在操作结果:队列S被销毁Print(S)初始条件:队列S已存在操作结果:输出队列S} Queue operationBiTree operation{InitBiTree( &T )// 操作结果:构造空二叉树T。
DestroyBiTree( &T )// 初始条件:二叉树T已存在。
// 操作结果:销毁二叉树T。
CreateBiTree( &T, definition )// 初始条件:definition给出二叉树T的定义。
// 操作结果:按definiton构造二叉树T。
数据结构实验三——二叉树基本操作及运算实验报告
![数据结构实验三——二叉树基本操作及运算实验报告](https://img.taocdn.com/s3/m/d4dbf1882cc58bd63086bd05.png)
《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。
问题分析:二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。
由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。
处理本问题,我觉得应该:1、建立二叉树;2、通过递归方法来遍历(先序、中序和后序)二叉树;3、通过队列应用来实现对二叉树的层次遍历;4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等;5、运用广义表对二叉树进行广义表形式的打印。
算法规定:输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。
输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。
对二叉树的一些运算结果以整型输出。
程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。
计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。
对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。
测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E预测结果:先序遍历ABCDEGF中序遍历CBEGDFA后序遍历CGEFDBA层次遍历ABCDEFG广义表打印A(B(C,D(E(,G),F)))叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2查找5,成功,查找的元素为E删除E后,以广义表形式打印A(B(C,D(,F)))输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B预测结果:先序遍历ABDEHCFG中序遍历DBHEAGFC后序遍历DHEBGFCA层次遍历ABCDEFHG广义表打印A(B(D,E(H)),C(F(,G)))叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3查找10,失败。
实验三 二叉树的基本操作实现及其应用
![实验三 二叉树的基本操作实现及其应用](https://img.taocdn.com/s3/m/009c090c7cd184254b353588.png)
二叉树的基本操作实现及其应用一、实验目的1.熟悉二叉树结点的结构和对二叉树的基本操作。
2.掌握对二叉树每一种操作的具体实现。
3.学会利用递归方法编写对二叉树这种递归数据结构进行处理的算法。
4.会用二叉树解决简单的实际问题。
二、实验内容设计程序实现二叉树结点的类型定义和对二叉树的基本操作。
该程序包括二叉树结构类型以及每一种操作的具体的函数定义和主函数。
1 按先序次序建立一个二叉树,2按(A:先序 B:中序 C:后序)遍历输出二叉树的所有结点以上比做,以下选做3求二叉树中所有结点数4求二叉树的深度三、实验步骤㈠、数据结构与核心算法的设计描述/* 定义DataType为char类型 */typedef char DataType;/* 二叉树的结点类型 */typedef struct BitNode{ DataType data;struct BitNode *lchild,*rchild;}*BitTree;相关函数声明:1、/* 初始化二叉树,即把树根指针置空 */void BinTreeInit(BitTree *BT){BT=(BitTree)malloc(sizeof(BitNode));BT->data=NULL;cout<<"二叉树初始化成功!"<<endl;}2、/* 按先序次序建立一个二叉树*/int BinTreeCreat(BitTree &BT){char ch;cin>>ch;if(ch=='#') BT=NULL;else{if(!(BT=(BitTree)malloc(sizeof(BitNode))))exit(0);BT->data=ch;BinTreeCreat(BT->lchild);BinTreeCreat(BT->rchild);}return 0;}3、/* 检查二叉树是否为空 */void BinTreeEmpty(BitTree &BT){if(BT->data==NULL)cout<<"是空二叉树!"<<endl;elsecout<<"不是空二叉树!"<<endl;}4、/*按任一种遍历次序(包括按先序、中序、后序、按层次)输出二叉树中的所有结点 */void BinTraverse(BitTree &BT)//按先序序列建立二叉树{if(BT!=NULL){cout<<BT->data;BinTraverse(BT->lchild);BinTraverse(BT->rchild);}}5、/* 求二叉树的深度 */int BinTreeDepth(BitTree BT){int depthval;if(BT){int depthLeft=BinTreeDepth(BT->lchild);int depthRight=BinTreeDepth(BT->rchild);depthval=1+(depthLeft>depthRight?depthLeft:depthRight);}else depthval=0;return depthval;}6、/* 求二叉树中所有结点数 */int BinTreeCount(BitTree BT){int node;if(BT){int lchild=BinTreeCount(BT->lchild);int rchild=BinTreeCount(BT->rchild);node=lchild+rchild+1;}elsenode=0;return node;}㈡、函数调用及主函数设计㈢程序调试及运行结果分析测试数据: 1、初始化二叉树; 2、按先序序列建立二叉树;3、判断二叉树是否为空;4、先序序列遍历二叉树;5、求二叉树的深度;6、求二叉树节点的个数。
二叉树的建立及应用
![二叉树的建立及应用](https://img.taocdn.com/s3/m/98127e8884868762caaed569.png)
实验3:二叉树的建立及应用1、实验目的∙熟练掌握二叉树的二叉链表存储结构∙掌握二叉树的非线性和递归性特点∙熟练掌握二叉树的递归遍历操作的实现方法∙加深对二叉树结构和性质的理解,逐步培养解决实际问题的编程能力2、实验内容a)按先序序列输入字符序列,建立二叉链表。
如ABC□□DE□G□□F□□□(□表示空格)b)中序遍历二叉树:递归算法。
c)后序遍历二叉树:递归算法。
d)求二叉树的高度、深度。
e)求二叉树的叶子个数。
f)应用训练: 建立表达树,并计算表达式2^(1+3)的值。
提示:若求表达式4+5的值,则输入其表达树的先序字符序列:+4□□5□□3、实验指导a)首先将二叉树的链式存储结构定义放在一个头文件:如取名为BinTreeDef.h。
b)将二叉树的基本操作算法也集中放在一个文件之中,如取名为BinTreeAlgo.h。
包含关于二叉树的链式结构操作的一些基本算法,如:InitBiTree、DestroyBiTree、CreateBiTree、BiTreeEmpty、BiTreeDepth、Root、PreOrderTraverse、InOrderTraverse 等。
c)将函数的测试和主函数组合成一个文件,如取名为BinTreeUse.cpp。
4、参考程序#include"pubuse.h" /* 与实验一的意义相同*/typedef char TElemType;TElemType Nil=' ';#include"BinTreeDef.h" /* 二叉树链式存储结构定义*/#include"BinTreeAlgo.h" /* 二叉树基本算法和扩展算法定义*/ double eValue(BiTree t)// 求表达树值{if(t!=NULL){if(isdigit(t->data)) //如果遍历到的是数字return t->data-'0';else //如果遍历到的是运算符结点{char op=t->data; //获取运算符double x=eValue(t->lchild);//求左表达树的值double y=eValue(t->rchild); //求左表达树的值double res;switch(op) //根据不同的运算符对数据进行计算{case '+':res=x+y;break;case '-':res=x-y;break;case '*':res=x*y;break;case '/':res=x/y;break;case '^':res=pow(x,y);break;case '%':res=int(x)%int(y);break;};return res;};}elsereturn 0;}void main(){BiTree T,et;char s;//加一个接收回车的字符TElemType e1;InitBiTree(T);printf("请先序输入二叉树:(如:AB 三个空格表示A为根结点,B为左子树的二叉树)\n");CreateBiTree(T); //创建二叉树e1=Root(T);if(e1!=Nil)printf("二叉树的根为: %c\n",e1);elseprintf("树空,无根\n");printf("中序递归遍历二叉树:");InOrderTraverse(T); //中序遍历二叉树printf("\n");printf("后序递归遍历二叉树:");PostOrderTraverse(T); //后序遍历二叉树printf("\n");printf("二叉树的结点数=%d\n",Nodes(T));printf("二叉树的叶子结点数=%d\n",LeafNodes(T));printf("按竖向树状打印的二叉树:\n");PrintTree(T,0);scanf("%c",&s); //加上这一句,对数字输入没有影响,只接收回车//fflush(stdin); //清空输入缓冲区;printf("请先序输入表达式2^(1+3)的二叉树:)\n");InitBiTree(et);CreateBiTree(et);printf("后缀表达式:");PostOrderTraverse(et);printf("=%f\n",eV alue(et));}5、实验结果6、实验分析本次试验是对二叉树的进一步考察,首先试验前必须清楚各种遍历:(1)先序遍历:访问根;按先序遍历左子树;按先序遍历右子树(2)中序遍历:按中序遍历左子树;访问根;按中序遍历右子树(3)后序遍历:按后序遍历左子树;按后序遍历右子树;访问根(4)层次遍历:即按照层次访问,通常用队列来做。
二叉树及其应用
![二叉树及其应用](https://img.taocdn.com/s3/m/b20f07e3f61fb7360b4c65db.png)
实验5:二叉树及其应用一、实验目的树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。
二、问题描述首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。
其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。
如算术表达式:a+b*(c-d)-e/f三、实验要求1、 如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算 a) 统计叶子结点的个数。
b) 求二叉树的深度。
2、 十进制的四则运算的计算器可以接收用户来自键盘的输入。
3、 由输入的表达式字符串动态生成算术表达式所对应的二叉树。
4、 自动完成求值运算和输出结果。
四、实验环境PC 微机DOS 操作系统或 Windows 操作系统Turbo C 程序集成环境或 Visual C++ 程序集成环境五、实验步骤1、根据二叉树的各种存储结构建立二叉树;2、设计求叶子结点个数算法和树的深度算法;1、 根据表达式建立相应的二叉树,生成表达式树的模块; 4、根据表达式树,求出表达式值,生成求值模块; 1、 程序运行效果,测试数据分析算法。
-+/a*b-efCd六、测试数据1、输入数据:2.2*(3.1+1.20)-7.5/3正确结果:6.962、输入数据:(1+2)*3+(5+6*7);正确输出:56七、实验报告要求实验报告应包括以下几个部分:1、设计算术表达式树的存储结构;2、给出二叉树中叶子结点个数算法和树的深度算法描述;3、给出生成表达式树算法和求解算法描述;4、相应的程序要给出足够的注释部分;5、给出程序的测试结果;6、实验总结。
八、思考题1、分析利用完全二叉树的性质和二叉链表存储有什么不同?分析其优缺点。
2、增加输入表达式进行语法判错的功能。
实验源代码:#include<stdio.h>#include<iostream>#include<malloc.h>#define STACK_INIT_SIZE 100#define STACKINCREMENT 10#define ERROR 0#define NUMBER 1#define SIMBLE 2using namespace std;int OP[8] = { '+', '-', '*', '/', '(', ')', '#', 0 };typedef union{int Operator; // 操作符float Operand; // 操作数}Int_Float;typedef struct BinaryTreeNode{Int_Float Data;int IsOperator;struct BinaryTreeNode *RChild;struct BinaryTreeNode *LChild;}BiTreeNode, *lpBiTreeNode;// 表达式树typedef struct {lpBiTreeNode *base;lpBiTreeNode *top;int stacksize;}SqStack;// 栈int InitStack( SqStack &s ){s.base = (lpBiTreeNode *)malloc( STACK_INIT_SIZE*sizeof(lpBiTreeNode) );if(!s.base)return 0;s.top = s.base;s.stacksize = STACK_INIT_SIZE;return 1;}int Push( SqStack &s, lpBiTreeNode e ){if( s.top - s.base >= s.stacksize ){s.base = (lpBiTreeNode *)realloc( s.base, (s.stacksize + STACKINCREMENT)*sizeof(lpBiTreeNode) );if(!s.base)return 0;s.top = s.base + s.stacksize;s.stacksize += STACKINCREMENT;}*s.top = e;s.top ++;return 1;}int Pop( SqStack &s, lpBiTreeNode &e ){if( s.top == s.base )return 0;s.top --;e = *s.top;return 1;}lpBiTreeNode GetTop( SqStack s ){lpBiTreeNode e;if( s.top == s.base )return NULL;e = *(s.top -1);return e;}int IsEmpty( SqStack s ){if( s.top == s.base )return 1;elsereturn 0;}int In( int c, int* op ){ // 判断c 是否在op 中,op为以结尾的数组while( *op != 0 ){if( c == *op )return 1;op ++;}return 0;}int Precede( int theta1, int theta2 ){int i, j;int op_look[7][7] ={ { '>', '>', '<', '<', '<', '>', '>' },{ '>', '>', '<', '<', '<', '>', '>' },{ '>', '>', '>', '>', '<', '>', '>' },{ '>', '>', '>', '>', '<', '>', '>' },{ '<', '<', '<', '<', '<', '=', ' ' },{ '>', '>', '>', '>', ' ', '>', '>' },{ '<', '<', '<', '<', '<', ' ', '=' }};switch( theta1 ){case'+':i = 0;break;case'-':i = 1;break;case'*':i = 2;break;case'/':i = 3;break;case'(':i = 4;break;case')':i = 5;break;case'#':i = 6;break;default:return 0;}switch( theta2 ){case'+':j = 0;break;case'-':j = 1;break;case'*':j = 2;case'/':j = 3;break;case'(':j = 4;break;case')':j = 5;break;case'#':j = 6;break;default:return 0;}return op_look[i][j];}int isNum( int c ){if( c >= '0' && c <= '9' )return 1;else return 0;}int GetInput(Int_Float *Result){ // 返回值:无,1数字,2符号static int buffer = 0; // 缓存存储数字后的符号int c;Int_Float result;int IsNumber = 0; // 是否为数字int IsFloat = 0; // 是否为小数int i,t=1;result.Operand = 0;if(In(buffer, OP)){ // 缓存中有符号,返回result.Operator = buffer;buffer = 0;Result->Operator = result.Operator;return SIMBLE; // 符号}// 去前导空格c = getchar();while ( c == ' ' && c != 10 ){c = getchar();}while( c != ' ' && c != 10 ){ // 不是空格和回车if(isNum(c)){ // 是数字IsNumber = 1;c = c - 48; // 字符到整型if(IsFloat == 0)result.Operand = result.Operand*10 + c;result.Operand = result.Operand*10 + c;IsFloat ++;}}else if(c == '.'){if(IsFloat != 0){// 两个小数点Result->Operand = 0;return ERROR;}elseIsFloat = 1;}else if (In(c, OP)) {if(IsNumber){ // 数字后接符号if(IsFloat == 1){Result->Operand = 0;return ERROR;}else{buffer = c;for(i=0; i<IsFloat-1; i++)t*=10;Result->Operand = result.Operand/(float)t;return NUMBER; // 数字}}else {Result->Operator = c;return SIMBLE; // 符号}}c = getchar();}buffer = 0;if(IsNumber){if(IsFloat == 1){Result->Operand = 0;return ERROR;}else{for(i=0; i<IsFloat-1; i++)t*=10;Result->Operand = result.Operand/(float)t;return NUMBER;}}else if(result.Operand == 0){Result->Operand = 0;return ERROR;}else{Result->Operator = result.Operator;return SIMBLE;}}lpBiTreeNode CreateBiTree(){SqStack Operand; // 操作数SqStack Operator; // 操作符lpBiTreeNode pNode;lpBiTreeNode theta,a,b;Int_Float c;printf("输入算式");int r = GetInput(&c);InitStack(Operand);InitStack(Operator);pNode = (lpBiTreeNode)malloc(sizeof(BiTreeNode));pNode->Data.Operator = '#';pNode->IsOperator = 1;pNode->LChild = NULL;pNode->RChild = NULL;Push( Operator, pNode );while( !( r == SIMBLE && c.Operator == '#') || GetTop(Operator)->Data.Operator != '#' ){if(r == ERROR)return NULL;if( r == NUMBER ) {// 是数字pNode = (lpBiTreeNode)malloc(sizeof(BiTreeNode));pNode->Data.Operand = c.Operand;pNode->IsOperator = 0;pNode->LChild = NULL;pNode->RChild = NULL;Push(Operand,pNode);r = GetInput(&c);}else if( r == SIMBLE ) {// 是符号switch( Precede(GetTop(Operator)->Data.Operator, c.Operator) ){case'<': // 栈顶元素优先权低pNode = (lpBiTreeNode)malloc(sizeof(BiTreeNode));pNode->Data.Operator = c.Operator;pNode->IsOperator = 1;pNode->LChild = NULL;pNode->RChild = NULL;Push( Operator, pNode );r = GetInput(&c);break;case'=': // '(', ')'相遇,脱括号Pop( Operator, pNode );r = GetInput(&c);break;case'>': // 栈顶元素优先权高, 退栈并将运算结果入栈Pop( Operator, theta );Pop( Operand, b);Pop( Operand, a);theta->LChild = a;theta->RChild = b;Push(Operand, theta);break;}}}return GetTop(Operand);}bool calculate(lpBiTreeNode Root, float *result){float resultLchild;float resultRchild;if( Root != NULL ){if(Root->LChild == NULL && Root->RChild == NULL){*result = Root->Data.Operand;return true;}else if(Root->LChild == NULL || Root->RChild == NULL)return false;else{switch (Root->Data.Operator){case'+':if( calculate(Root->LChild, &resultLchild)==false )return false;if( calculate(Root->RChild, &resultRchild)==false )return false;*result = resultLchild + resultRchild;break;case'-':if( calculate(Root->LChild, &resultLchild)==false )return false;if( calculate(Root->RChild, &resultRchild)==false )return false;*result = resultLchild - resultRchild;break;case'*':if( calculate(Root->LChild, &resultLchild)==false )return false;if( calculate(Root->RChild, &resultRchild)==false )return false;*result = resultLchild * resultRchild;break;case'/':if( calculate(Root->LChild, &resultLchild)==false )return false;if( calculate(Root->RChild, &resultRchild)==false )return false;*result = resultLchild / resultRchild;break;}}}return true;}int getLeafNum(lpBiTreeNode Root){int LeafnumLchild;int LeafnumRchild;if( Root != NULL ){if(Root->LChild == NULL && Root->RChild == NULL)return 1;else{LeafnumLchild = getLeafNum(Root->LChild);LeafnumRchild = getLeafNum(Root->RChild);return LeafnumLchild + LeafnumRchild;}}return 0;}int getDepth(lpBiTreeNode Root){int LeafDepthL;int LeafDepthR;if( Root != NULL ){if(Root->LChild == NULL && Root->RChild == NULL)return 0;else{LeafDepthL = getDepth(Root->LChild);LeafDepthR = getDepth(Root->RChild);return 1 + (LeafDepthL>LeafDepthR?LeafDepthL:LeafDepthR);}}return 0;}void main(){lpBiTreeNode Root;float result;if( Root = CreateBiTree() ){printf( "叶子数: %d\n", getLeafNum(Root) );printf( "深度: %d\n", getDepth(Root) );if( calculate(Root, &result) ){printf("Result: %0.2f\n", result);}elseprintf("ERROR");}elseprintf("INPUT ERROR\n");system("pause");}实验截图。
实验报告 实验三 二叉排序树的建立和查找
![实验报告 实验三 二叉排序树的建立和查找](https://img.taocdn.com/s3/m/5927821ecc7931b765ce1568.png)
实验三二叉排序树的建立和查找一、实验目的1.掌握二叉排序树的建立算法2.掌握二叉排序树查找算法。
二、实验环境操作系统和C语言系统三、预习要求复习二叉排序树的生成及查找算法,编写完整的程序。
四、实验内容实现二叉排序树上的查找算法。
具体实现要求:用二叉链表做存储结构,输入键值序列,建立一棵二叉排序树并在二叉排序树上实现查找算法。
五、参考算法#include <stdio.h>#include <stdlib.h>typedef int InfoType;typedef int KeyType; /*假定关键字类型为整数*/typedef struct node /*结点类型*/{KeyType key; /*关键字项*/InfoType otherinfo; /*其它数据域,InfoType视应用情况而定,下面不处理它*/struct node *lchild,*rchild; /*左右孩子指针*/}BSTNode;typedef BSTNode *BSTree; /*BSTree是二叉排序树的类型*/BSTNode *SearchBST(BSTree T,KeyType key){ /*在二叉排序树T上查找关键字为key的结点,成功时返回该结点位置,否则返回NULL*/if(T==NULL||key==T->key) /*递归的终结条件*/return T; /*若T为空,查找失败;否则成功,返回找到的结点位置*/if(key<T->key)return SearchBST(T->lchild,key);elsereturn SearchBST(T->rchild,key); /*继续在右子树中查找*/}void InsertBST(BSTree *T,int key){ /*插入一个值为key的节点到二叉排序树中*/BSTNode *p,*q;if((*T)==NULL){ /*树为空树*/(*T)=(BSTree)malloc(sizeof(BSTNode));(*T)->key=key;(*T)->lchild=(*T)->rchild=NULL;}else{p=(*T);while(p){q=p;if(p->key>key)p=q->lchild;else if(p->key<key)p=q->rchild;else{printf("\n 该二叉排序树中含有关键字为%d的节点!\n",key);return;}}p=(BSTree)malloc(sizeof(BSTNode));p->key=key;p->lchild=p->rchild=NULL;if(q->key>key)q->lchild=p;elseq->rchild=p;}}BSTree CreateBST(void){ /*输入一个结点序列,建立一棵二叉排序树,将根结点指针返回*/BSTree T=NULL; /*初始时T为空树*/KeyType key;scanf("%d",&key); /*读入一个关键字*/while(key){ /*假设key=0是输入结束标志*/ InsertBST(&T,key); /*将key插入二叉排序树T*/scanf("%d",&key); /*读入下一关键字*/}return T; /*返回建立的二叉排序树的根指针*/ }void ListBinTree(BSTree T) /*用广义表示二叉树*/{if(T!=NULL){printf("%d",T->key);if(T->lchild!=NULL||T->rchild!=NULL){printf("(");ListBinTree(T->lchild);if(T->rchild!=NULL)printf(",");ListBinTree(T->rchild);printf(")");}}}void main(){BSTNode *SearchBST(BSTree T,KeyType key);void InsertBST(BSTree *Tptr,KeyType key);BSTree CreateBST();void ListBinTree(BSTree T);BSTree T;BSTNode *p;int key;printf("请输入关键字(输入0为结束标志):\n");T=CreateBST();ListBinTree(T);printf("\n");printf("请输入欲查找关键字:");scanf("%d",&key);p=SearchBST(T,key);if(p==NULL)printf("没有找到%d!\n",key);elseprintf("找到%d!\n",key);ListBinTree(p);printf("\n");}实验中出现的问题及对问题的解决方案输入数据时,总是不能得到结果,原因是在建立二叉树函数定义中,是对指针的值进行了修改。
数据结构二叉树实验报告
![数据结构二叉树实验报告](https://img.taocdn.com/s3/m/16191703e518964bce847c4c.png)
实验三二叉树的遍历一、实验目的1、熟悉二叉树的结点类型和二叉树的基本操作。
2、掌握二叉树的前序、中序和后序遍历的算法。
3、加深对二叉树的理解,逐步培养解决实际问题的编程能力。
二、实验环境运行C或VC++的微机。
三、实验内容1、依次输入元素值,以链表方式建立二叉树,并输出结点的值。
2、分别以前序、中序和后序遍历二叉树的方式输出结点内容。
四、设计思路1. 对于这道题,我的设计思路是先做好各个分部函数,然后在主函数中进行顺序排列,以此完成实验要求2.二叉树采用动态数组3.二叉树运用9个函数,主要有主函数、构建空二叉树函数、建立二叉树函数、访问节点函数、销毁二叉树函数、先序函数、中序函数、后序函数、范例函数,关键在于访问节点五、程序代码#include <stdio.h>#include <stdlib.h>#include <malloc.h>#define OK 1#define ERROR 0typedef struct TNode//结构体定义{-int data; //数据域struct TNode *lchild,*rchild; // 指针域包括左右孩子指针}TNode,*Tree;void CreateT(Tree *T)//创建二叉树按,依次输入二叉树中结点的值{int a;scanf("%d",&a);if(a==00) // 结点的值为空*T=NULL;else // 结点的值不为空{*T=(Tree)malloc(sizeof(TNode));if(!T){printf("分配空间失败!!TAT");exit(ERROR);}(*T)->data=a;CreateT(&((*T)->lchild)); // 递归调用函数,构造左子树CreateT(&((*T)->rchild)); // 递归调用函数,构造右子树}}void InitT(Tree *T)//构建空二叉树{T=NULL;}void DestroyT(Tree *T)//销毁二叉树{if(*T) // 二叉树非空{DestroyT(&((*T)->lchild)); // 递归调用函数,销毁左子树DestroyT(&((*T)->rchild)); // 递归调用函数,销毁右子树free(T);T=NULL;}}void visit(int e)//访问结点{printf("%d ",e);}-void PreOrderT(Tree *T,void(*visit)(int))//先序遍历T{if(*T) // 二叉树非空{visit((*T)->data); // 先访问根结点PreOrderT(&((*T)->lchild),visit); // 递归调用函数,先序遍历左子树PreOrderT(&((*T)->rchild),visit); // 递归调用函数,先序遍历右子树}}void InOrderT(Tree *T,void(*visit)(int)){if(*T){InOrderT(&((*T)->lchild),visit); // 递归调用函数,中序遍历左子树visit((*T)->data); // 访问根结点InOrderT(&((*T)->rchild),visit); // 递归调用函数,中序遍历右子树}}void PostOrderT(Tree *T,void(*visit)(int)){if(*T){PostOrderT(&((*T)->lchild),visit); // 递归调用函数,后序遍历左子树PostOrderT(&((*T)->rchild),visit); // 递归调用函数,序遍历右子树visit((*T)->data); // 访问根结点}}void example(){int i;printf("如果你想建立如图所示的二叉树\n");printf("\n");printf(" 1 \n");printf(" / \\ \n");printf(" 3 3 \n");printf(" / \\ \\ \n");printf(" 4 5 7 \n");printf("\n");printf("请输入:1 3 4 00 00 5 00 00 3 00 7 00 00\n");printf("\n按先序次序输入二叉树中结点的值(输入00表示节点为空)\n");for(i=0;i<71;i++)printf("*");printf("\n");}int main (){Tree T;printf("**************欢迎使用!**************潘俊达\n"); example();printf("\n请输入所要建立的二叉树:\n");CreateT(&T);InitT(&T);int i;printf("先序遍历二叉树:\n");PreOrderT(&T,visit);printf("\n");printf("\n中序遍历二叉树:\n");InOrderT(&T,visit);printf("\n");printf("\n后序遍历二叉树:\n");PostOrderT(&T,visit);printf("\n");system("PAUSE");return 0;}六、程序截图1.范例函数显示,并输入先序二叉树节点值2.先序遍历二叉树3.中序遍历二叉树3.后序遍历二叉树。
实验3 二叉树的应用
![实验3 二叉树的应用](https://img.taocdn.com/s3/m/5bc78413cc7931b765ce15c5.png)
实验五:二叉树的应用一、实验预备知识1 树是一种非线性的结构,它具有递归特点。
2 二叉树有四种遍历方法,分别为:先根,后根、中根和层次。
掌握四种遍历的规则。
(每个结点都访问,并且只访问一次)二、实验目的1 掌握二叉树的逻辑结构特性,以及各种存储结构的特点及适用范围。
2 掌握用指针类型描述、访问和处理二叉树的各种运算的实现算法。
三、实验内容1 编写采用二叉链表形式存储的二叉树的创建算法。
2 编写二叉树的先序、中序、后序遍历的递归算法、先序和中序的非递归算法和按层遍历的算法。
2 编写将一棵二叉树的所有左右子树进行交换的算法。
3 编写统计二叉树中叶子结点的算法。
4编写一个主函数,将上面函数连在一起,构成一个完整的程序。
5将实验源程序调试并运行。
四、实验要求建立的二叉树为:AB CD E FG H#include<iostream>using namespace std;typedef char datatype;typedef struct node{datatype data;struct node *lchild,*rchild;}bintnode;typedef bintnode *bintree;typedef struct stack{bintree data[100];int tag[100];int top;}seqstack;创建二叉树算法:void CreateBinTree(bintree *t){char ch;if((ch=getchar())=='0')(*t)=NULL;else{*t=new bintnode ;(*t)->data=ch;CreateBinTree(&(*t)->lchild);CreateBinTree(&(*t)->rchild);}}前序遍历递归算法:void Preorder(bintree t){if(t){cout<<t->data<<" ";Preorder(t->lchild);Preorder(t->rchild);}}中序遍历递归算法:void Inorder(bintree t){if(t){Inorder(t->lchild);cout<<t->data<<" ";Inorder(t->rchild);}}后序遍历递归算法:void Postorder(bintree t){if(t){Postorder(t->lchild);Postorder(t->rchild);cout<<t->data<<" ";}}void Push(seqstack *s,bintree t) {s->data[++s->top]=t;}bintree Pop(seqstack *s){if(s->top!=-1){s->top--;return (s->data[s->top+1]);}elsereturn NULL;}前序遍历非递归算法:void Preorder1(bintree t){seqstack s;s.top=-1;while((t)||(s.top!=-1)){while(t){cout<<t->data<<" ";s.top++;s.data[s.top]=t;t=t->lchild;}if(s.top>-1){t=Pop(&s);t=t->rchild;}}}中序遍历非递归算法:void Inorder1(bintree t){seqstack s;s.top=-1;while((t!=NULL)||(s.top!=-1)){while(t){Push(&s,t);t=t->lchild;}if(s.top!=-1){t=Pop(&s);cout<<t->data<<" ";t->rchild;}}}层次遍历算法:void Levelorder(bintree t){bintree queue[100];int front,rear;if(t==NULL)return;front=-1;rear=0;queue[rear]=t;while(front!=rear){front++;cout<<queue[front]->data<<" ";if(queue[front]->lchild!=NULL){rear++;queue[rear]=queue[front]->lchild;}if(queue[front]->rchild!=NULL){rear++;queue[rear]=queue[front]->rchild;}}}遍历叶子节点算法:void CountLeaf(bintree t){if(!t)return;if(!(t->lchild||t->rchild))cout<<t->data<<" ";CountLeaf(t->lchild);CountLeaf(t->rchild);}交换左右子树算法:void SwapBinTree(bintree t){bintree s;if(t){SwapBinTree(t->lchild);SwapBinTree(t->rchild);s=t->lchild;t->lchild=t->rchild;t->rchild=s;}}主函数实现:void main(){bintree root;cout<<"***********************************************************"<<en dl;cout<<"请按前序遍历次序顺序读入所要生成的二叉树:";CreateBinTree(&root);cout<<"***********************************************************"<<en dl;cout<<"*******************************************"<<endl;cout<<"递归实现前序遍历结果:";Preorder(root);cout<<endl;cout<<"\n递归实现中序遍历结果:";Inorder(root);cout<<endl;cout<<"\n递归实现后序遍历结果:";Postorder(root);cout<<endl;cout<<"*******************************************"<<endl;cout<<"*******************************************"<<endl;cout<<"非递归实现前序遍历结果:";Preorder1(root);cout<<endl;cout<<"\n非递归实现中序遍历结果:";Inorder(root);cout<<endl;cout<<"\n层次遍历结果:";Levelorder(root);cout<<endl;cout<<"\n叶子结点为:";CountLeaf(root);cout<<endl;cout<<"*******************************************"<<endl;cout<<"*******************************************"<<endl;printf("交换左右子树后遍历如下:");cout<<endl;SwapBinTree(root);cout<<"\n递归实现前序遍历结果:";Preorder(root);cout<<endl;cout<<"\n递归实现中序遍历结果:";Inorder(root);cout<<endl;cout<<"\n递归实现后序遍历结果:";Postorder(root);cout<<endl;cout<<"*******************************************"<<endl; }五、实验结果:。
实验三 树及其应用2
![实验三 树及其应用2](https://img.taocdn.com/s3/m/2323904669eae009581bec35.png)
实验三树及其应用实验目的:1.熟悉树的各种存储结构的特性。
2.应用树的结构解决具体问题。
实验内容:1.树的各种存储结构。
2.应用树的结构解决具体问题。
问题描述:很多涉及树的操作的算法都是以树的遍历操作为基础的。
试写一个程序,演示在二叉树上访问全部结点的操作。
实验要求:以二叉链表为存储结构,建立一棵二叉树,并对该二叉树进行先序、中序和后序遍历,分别输出每种遍历下的结点访问序列。
(1)把以下程序补充完整(2)编程输出二叉树的叶子结点测试数据:实验代码:#include<iostream.h>struct node{char data;node *left;node *right;};class tree{public:tree();void Create(node*);void Delete(node*);void Q(node*);void Z(node*);void H(node*);~tree();private:static node *root;};node* tree::root=0;tree::tree(){cout<<"输入树的根节点(如果为空输入#):\t";root=new node;cin>>root->data;Create(root);}void tree::Create(node *p){if(p){char x,y; node *q;cout<<"输入节点"<<p->data<<"的左孩子和右孩子:\t"; cin>>x>>y;if(x=='#')p->left=0;else{q=new node;q->data=x;p->left=q;}if(y=='#')p->right=0;else{q=new node;q->data=y;p->right=q;}Create(p->left);Create(p->right);}}//前序遍历void tree::Q(node *p=root){if(p){cout<<p->data<<' ';Q(p->left);Q(p->right);}}//中序遍历void tree::Z(node *p=root) {//写出算法的具体实现}//后序遍历void tree::H(node *p=root) {//写出算法的具体实现}//实现输出叶子结点的算法//tree::~tree(){Delete(root);}void tree::Delete(node *p) {if(p){Delete(p->left);Delete(p->right);delete p;}}void main(){tree h;cout<<"树的前序遍历:";h.Q();cout<<"\n树的中序遍历:";h.Z();cout<<"\n树的后序遍历:";h.H();}。
二叉树的基本操作实验
![二叉树的基本操作实验](https://img.taocdn.com/s3/m/1d3877bb2af90242a895e5c8.png)
图(1)
图表1
else if(a==4)
{
printf("层序遍历:");
howmuch(T,2);
}
else if(a==5)
{
printf("总节点数:");
howmuch(T,0);
}
else if(a==6)
{
printf("总叶子数:");
howmuch(T,1);
}
else if(a==7)
{
printf("树的深度:");
二 概要设计
功能实现
1.int CreatBiTree(BiTree &T)用递归的方法先序建立二叉树, 并用链表储存该二叉树
2.int PreTravel(BiTree &T)前序遍历
3.intMidTravel(BiTree &T)中序遍历
4.intPostTravel(BiTree &T)后序遍历
实验三 二叉树的基本运算
一、实验目的
1、使学生熟练掌握二叉树的逻辑结构和存储结构。
2、熟练掌握二叉树的各种遍历算法。
二、实验内容
[问题描述]
建立一棵二叉树,试编程实现二叉树的如下基本操作:
1. 按先序序列构造一棵二叉链表表示的二叉树T;
2. 对这棵二叉树进行遍历:先序、中序、后序以及层次遍历,分别输出结点的遍历序列;
5.int Depth(BiTree &T) //计算树的深度
6.inthowmuch(BiTree T,int h)采用树节点指针数组,用于存放遍历到的元素地址,如果有左孩子,存入地址,j加一 ,否则没操作,通过访问数组输出层次遍历的结果。k计算叶子数,j为总节点。
实验三 树和二叉树的建立和应用
![实验三 树和二叉树的建立和应用](https://img.taocdn.com/s3/m/f1408fe3551810a6f524865d.png)
实验三 二叉树的建立和应用
1、实验目的
(1)熟练掌握树的基本概念、二叉树的基本操作及在链式存储结构上的实现;
(2)重点掌握二叉树的生成、遍历及求叶子结点算法;
(3)掌握运用递归方式描述算法及编写递归C 程序的方法,提高算法分析和程序设计能力。
2、实验内容
1)按照已知二叉树,从键盘读入节点字符,建立二叉树(例如,ABD#G###CE##FH###) 2)分别采用先序、中序、后序及层次遍历该二叉树,分别输出遍历结果。
3)应用:求出该数的叶子结点数。
3、实验步骤
(1)仔细分析实验内容,给出其算法和流程图;
(2)用C 语言实现该算法;
(3)给出测试数据,并分析其结果;
(4)在实验报告册上写出实验过程。
4、测试数据 1)所创建的树如右图所示:
2)遍历结果: 先序序列: ABDGCEFH
中序序列: DGBAECHF
后序序列: GDBEHFCA 层次遍历:ABCDEFGH
3)叶子结点数:3
5、树的结点结构定义如下: typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
6、实验报告要求
实验三 二叉树的建立和应用
G H B C D E F A
姓名:班级:学号:日期:实验目的:
实验内容:
基本思想、原理和算法描述:
源程序:
运行结果分析:
实验总结:。
数据结构实验三二叉树实验报告
![数据结构实验三二叉树实验报告](https://img.taocdn.com/s3/m/06785d26a32d7375a417806f.png)
数据结构实验报告实验名称:实验三——二叉树学生姓名: XX班级:班内序号:学号:日期:1.实验要求1.1实验目的通过选择下面两个题目之一进行实现,掌握如下内容:掌握二叉树基本操作的实现方法了解赫夫曼树的思想和相关概念学习使用二叉树解决实际问题的能力1.2实验内容根据二叉树的抽象数据类型的定义,使用二叉链表实现一个二叉树。
二叉树的基本功能:1、二叉树的建立2、前序遍历二叉树3、中序遍历二叉树4、后序遍历二叉树5、按层序遍历二叉树6、求二叉树的深度7、求指定结点到根的路径8、二叉树的销毁9、其他:自定义操作编写测试main()函数测试线性表的正确性2. 程序分析2.1 存储结构二叉树的结点结构二叉树的二叉链表存储示意图2.2 关键算法分析(1)创建一个二叉树伪代码实现:1.定义根指针,输入节点储存的data,若输入“#”,则该节点为空;2.申请一个新节点,判断它的父结点是否不为空,如果不为空在判断其为左或者右孩子,并把地址付给父结点,把data写入。
代码实现void BiTree::create(BiNode* &R,int data[],int i,int n)//创建二叉树{if(i<=n){R=new BiNode;R->data=data[i-1];create(R->lch,data,2*i,n);create(R->rch,data,2*i+1,n);}else R=NULL;}(2)前序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.打印起始节点的值,并先后在左子数右子数上递归调用打印函数代码实现void BiTree::preorder(BiNode* R)//前序遍历{if(R!=NULL){cout<<R->data;preorder(R->lch);preorder(R->rch);}}时间复杂度:O(n)(3)中序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.递归遍历左子树3.打印根节点数据域内容4.递归遍历右子树代码实现void BiTree::inorder(BiNode* R)//中序遍历{if(R!=NULL){inorder(R->lch);cout<<R->data;inorder(R->rch);}}时间复杂度:O(n)(4)后序遍历伪代码实现:1.设置递归边界条件:if root==null则停止递归2.递归遍历左子树3.递归遍历右子树4.访问根结点数据域代码实现void BiTree::postorder(BiNode* R)//后序遍历{if(R!=NULL){postorder(R->lch);postorder(R->rch);cout<<R->data;}}时间复杂度:O(n)(5)层序遍历伪代码实现1.队列Q及所需指针的定义和初始化2.如果二叉树非空,将根指针入队3.循环直到队列Q为空3.1 q=队列Q的队头元素出队3.2 访问节点q的数据域 cout<<q->data<<" ";3.3 若节点q存在左孩子,则将左孩子指针入队3.4若节点q存在右孩子,则将右孩子指针入队代码实现void BiTree::levelordre(BiNode* R)//层序遍历{BiNode*queue[maxsize];int f=0,r=0;if(R!=NULL)queue[++r]=R;while(f!=r){BiNode*p=queue[++f];cout<<p->data;if(p->lch!=NULL)queue[++r]=p->lch;if(p->rch!=NULL)queue[++r]=p->rch;}}时间复杂度:O(n)(6)计算二叉树深度伪代码实现:1. 定义和初始化计数深度的参数2.如果根节点为空,return03.如果根节点为非空,递归调用自身的到叶子节点到根的路径长度,输出其中较大的作为树的深度代码实现int BiTree::depth(BiNode* root)//求二叉树深度{int ld,rd;if (root!=NULL){ld = 1+depth(root->lch);rd = 1+depth(root->rch);return ld>rd?ld:rd;}else return 0;}时间复杂度:O(n)(7)输出指定结点到根结点的路径伪代码实现:1.建立一个存储路径结点结构,定义和初始化结构体的数组2.当root不为空或top为0时,进入循环3.当此时root所指的节点的数据不为指定数据时,将root指向它的左孩子4.当此时root所指的节点的数据为指定数据时,访问其数据域并输出代码实现bool BiTree::printPath(BiNode* root, int data)//打印指定结点到根节点的路径{if (root == NULL)return false;if (root->data == data || printPath(root->lch,data) ||printPath(root->rch,data)){cout<<root->data;return true;}return false;}3. 程序运行结果3.1测试主函数流程图:3.2测试条件对如下二叉树: 补全后的二叉树:按层序遍历的输入方法为:ABC#EFGH###I###J###@ 3.3程序运行结果为:4. 总结出现的问题及改进:刚开始编译正确但是输出结果异常,纪念馆仔细检查发现二叉树创建有问题,经过仔细修改,发现形参表示错误,*&,指针的引用,作为输入时,既把指针的值传入函数内部,又可以将指针的关系传递到函数内部;作为输出,由于算法中修改了指针的值,可以将新值传入到函数内部。
二叉树的应用实验报告
![二叉树的应用实验报告](https://img.taocdn.com/s3/m/4129ab1ca8956bec0875e32a.png)
实验报告课程名称____数据结构上机实验__________ 实验项目______二叉树的应用 ____________实验仪器________PC机___________________系别____________________________专业_____________________________班级/学号____________________________学生_____________________________实验日期_______________________成绩_______________________指导教师_______________________实验三.二叉树的应用1.实验目的:掌握二叉树的链式存储结构和常用算法。
利用哈夫曼树设计最优压缩编码。
2.实验容:1)编写函数,实现建立哈夫曼树和显示哈夫曼树的功能。
2)编写函数,实现生成哈夫曼编码的功能。
3)编写主函数,从终端输入一段英文文本;统计各个字符出现的频率,然后构建哈夫曼树并求出对应的哈夫曼编码;显示哈夫曼树和哈夫曼编码。
选做容:修改程序,选择实现以下功能:4)编码:用哈夫曼编码对一段英文文本进行压缩编码,显示编码后的文本编码序列;5)统计:计算并显示文本的压缩比例;6)解码:将采用哈夫曼编码压缩的文本还原为英文文本。
3.算法说明:1)二叉树和哈夫曼树的相关算法见讲义。
2)编码的方法是:从头开始逐个读取文本字符串中的每个字符,查编码表得到它的编码并输出。
重复处理直至文本结束。
3)解码的方法是:将指针指向哈夫曼树的树根,从头开始逐个读取编码序列中的每位,若该位为1则向右子树走,为0则向左子树走。
当走到叶子节点时,取出节点中的字符并输出。
重新将指针放到树根,继续以上过程直至编码序列处理完毕。
4)压缩比例的计算:编码后的文本长度为编码序列中的0和1,的个数,原文本长度为字符数*8。
两者之比即为压缩比。
4.实验步骤:实现哈夫曼树的编码序列操作:int i=0,j=0;huffnode p;p=tree[2*n-2];//序号2*n-2节点就是树根节点while(hfmstr[i]!='\0')//从头开始扫描每个字符,直到结束{while(p.lchild!=-1&&p.rchild!=-1)if(hfmstr[i]=='0')//为0则向左子树走{p=tree[p.lchild];//取出叶子节点中的字符}else if(hfmstr[i]=='1')//为1则向右子树走{p=tree[p.rchild];//取出叶子节点中的字符}i++;}decodestr[j]=p.data;j++;//对字符进行译码,结果放在decodestr字符串中p=tree[2*n-2];//返回根节点}}程序修改后完整源代码如下:#include <stdio.h>#include <stdlib.h>#include <string.h>#include <limits.h>//专门用于检测整型数据数据类型的表达值围#define N 96 //ASCII字符集包含至多N个可见字符typedef struct //Huffman树节点定义{ char data; //字符值int weight; //权重int lchild; //左子结点int rchild; //右子结点} huffnode; //huffman节点类型struct charcode{ int count; //字符出现的次数(频率)char code[N]; //字符的Huffman编码} codeset[N]; //编码表,长为N,每项对应一个ascii码字符,下标i的项对应ascii编码为i+32的字符huffnode * CreateHufftree(char data[], int weight[], int n) //建立Huffman树的算法{int i,k;int min1,min2,min_i1,min_i2;huffnode *tree;tree=(huffnode *)malloc((2*n-1)*sizeof(huffnode)); //为Huffman树分配2n-1个节点空间for (i=0;i<2*n-1;i++) //初始化,将各字符和其频率填入Huffman树,作为叶子结点{tree[i].lchild=tree[i].rchild=-1;if (i<n) {tree[i].data=data[i];tree[i].weight=weight[i];}else tree[i].data=' ';}for (i=n;i<2*n-1;i++) ////合并两棵树,作n-1遍min1=min2=INT_MAX; //INT_MAX为最大值min_i1=min_i2=-1;for (k=0;k<i;k++) ////查找定位两个最小权重节点if (tree[k].weight>=0) //仅在根节点中找if (tree[k].weight<min1){min2=min1;min_i2=min_i1;min1=tree[k].weight;min_i1=k;}elseif (tree[k].weight<min2) {min2=tree[k].weight;min_i2=k;}tree[i].weight=min1+min2; // 合并tree[min_i1].weight *= -1;tree[min_i2].weight *= -1;tree[i].lchild=min_i1;tree[i].rchild=min_i2;return tree;}void CreateHuffcode(huffnode tree[], int i, char s[])//已知tree[i]节点的编码序列为s,求该节点下所有叶子节点的编码序列。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验3 二叉树及其应用
实验目的
1.加深对二叉树的结构特性的理解;
2.熟练掌握二叉树的存储结构,特别是二叉链表类的描述及其实现方法;
3.熟练掌握二叉树的遍历算法原理及实现;
4.学会编写实现二叉树的各种算法;
5.掌握二叉树的应用方法。
实验学时:建议2~4学时
实验内容
内容1:二叉树及其操作
【问题描述】
设计二叉树的二叉链表类,操作主要有建二叉树、遍历二叉树、求该二叉树中、的结点个数等。
【基本要求】
(1)建立二叉树可用先序方式建立,也可根据二叉树的先序和中序序列建立。
(2)对二叉树的遍历可采用递归或非递归的算法。
【实现提示】
(1)二叉链表的结点结构描述
struct btnode{ // 定义结点类型
ElemType data; //数据域
btnode * lchild,* rchild; //左、右指针域/
}; // btnode
(2)可设计以下功能函数:
btnode* createbitree(); //建立二叉链表
void preorder(btnode* bt); //先序遍历二叉树
int sum(btnode* bt); //求二叉树中的结点个数
算法可用递归或非递归实现。
建立二叉树可用以下两种算法实现:
方案1:btnode * createBT ( ) //前序建树
{ bitree T; char ch;
cin >>ch ;
if(ch==’#’) return NULL; //二叉树为空
T=new BinTNode; //申请根结点
T->data=ch;
T->lchild=createBTpre(); //创建根的左子树
1
2
T->rchild=createBTpre(); //创建根的右子树 return T; }
方案2:btnode* createBT ( char *preorder, char *midorder) { //由前序preorder 和中序midorder 建树,返回根指针 if(strlen (preorder) ==0) return NULL; //空二叉树 T= new Node; //建立根结点 T->data=*preorder;
k=locate(midorder , *preorder); //找根在中序中的位置 lmidorder=fetch(midorder,0,k); //左子树的中序 lpreorder =fetch(preorder,1,k); //左子树的前序 rmidorder=fetch(midorder,k+1); //右子树的中序 rpreorder =fetch(preorder, k+1); //右子树的前序 T->lchild=createBT (lmidorder , lpreorder);//建根的左子树 T->rchild=createBT(rmidorder , rpreorder); //建根的右子树 return T; }
int sum(btnode* bt) //求二叉树中的结点个数 { if(!bt) return 0; //二叉树为空
return sum(bt->lchild) + sum(bt->rchild) +1; }
【选做内容】
(1) 对二叉树进行层次遍历算法。
(2) 求二叉树的深度、宽度等操作。
(3) 复制二叉树,交换二叉树中左右子树的问题怎么实现? 内容2:哈夫曼编码/译码器
【问题描述】设字符集为26个英文字母,其出现频度如下表所示。
先建哈夫曼树,再利用此树对报文“This program is my favorite”进行编码和译码。
51 48 1 15 63 57 20 32 5 1 频度
z y x w v u t 字符
1 16
1
18
8
23
80
频度
p 21 f q
15 g r 47 h s o n m l k j 字符 57 103 32 22 13 64 186 频度 i e d c b a 空格
字符
【基本要求】
算法具有以下功能:
(1)CreateHuffmanTree:根据给定字符的出现频数,建立其哈夫曼树。
(2)Encoding:对给定的原字符串进行编码。
(3)Decoding:对给定的编码串进行译码(或解码)。
(4)ShowHuffmanTree:显示哈夫曼树
【实现提示】
(1)用户界面可设计成模拟菜单方式。
(2)原字符串及编码串可从键盘输入。
(3)生成Huffman树的步骤如下:
①由给定的n 个权值{w1, w2, …, wn}构成n棵二叉树的集合(即森林)F =
{ T1, T2, …, Tn },其中每棵二叉树Ti 中只有一个带权为wi 的根结点,
其左右子树均空。
②在 F 中选取两棵根结点的权值最小的树做为左右子树构造一棵新的二叉
树,且置新的二叉树的根结点的权值为其左右子树上根结点的权值之和。
③在F 中删去这两棵树,同时将新得到的二叉树加入F中。
④重复②和③, 直到 F 只含一棵树为止。
这棵树便是赫夫曼树。
【选做内容】
(1)字符的出现频数能否从指定文件中统计而得?
(2)对指定的文件进行编码/解码。
3。