数据结构 二叉树的实现
二叉树的实现实验原理
二叉树的实现实验原理二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点,通常称为左子节点和右子节点。
二叉树的实现原理如下:1. 节点的定义:每个节点包含一个值和两个指针,分别指向左子节点和右子节点。
节点可以使用类或结构体来表示,具体的实现方式取决于编程语言。
2. 树的定义:树由节点组成,其中一个节点被指定为根节点。
根节点没有父节点,其他节点都有且只有一个父节点。
每个节点最多有两个子节点,即左子节点和右子节点。
3. 添加节点:向二叉树中添加节点时,需要遵循以下规则:- 如果树为空,将节点作为根节点添加到树中。
- 如果节点的值小于当前节点的值,将节点添加为当前节点的左子节点。
- 如果节点的值大于等于当前节点的值,将节点添加为当前节点的右子节点。
4. 遍历树:遍历二叉树可以按照不同的顺序进行,常见的遍历方式有三种:- 前序遍历(Preorder Traversal):先访问根节点,然后按照前序遍历方式遍历左子树,最后按照前序遍历方式遍历右子树。
- 中序遍历(Inorder Traversal):先按照中序遍历方式遍历左子树,然后访问根节点,最后按照中序遍历方式遍历右子树。
- 后序遍历(Postorder Traversal):先按照后序遍历方式遍历左子树,然后按照后序遍历方式遍历右子树,最后访问根节点。
遍历树的过程可以使用递归或迭代的方式来实现,具体的实现方法取决于编程语言和使用的数据结构。
5. 删除节点:删除二叉树中的节点时,需要考虑多种情况。
如果要删除的节点是叶子节点,可以直接删除它。
如果要删除的节点只有一个子节点,可以将子节点移动到要删除的节点的位置。
如果要删除的节点有两个子节点,可以选择将其中一个子节点替代要删除的节点,或者选择左子树的最大节点或右子树的最小节点替代要删除的节点。
根据上述原理,可以使用类或结构体等数据结构和递归或迭代的方式来实现二叉树。
具体的实现方法和细节可能因编程语言而异,但以上原理是通用的。
数据结构二叉树实验报告
一 、实验目的和要求(1)掌握树的相关概念,包括树、节点的度、树的度、分支节点、叶子节点、孩子节点、双亲节 点、树的深度、森林等定义。
(2)掌握树的表示,包括树形表示法、文氏图表示法、凹入表示法和括号表示法等。
(3)掌握二叉树的概念,包括二叉树、满二叉树和完全二叉树的定义。
(4)掌握二叉树的性质。
(5)重点掌握二叉树的存储结构,包括二叉树顺序存储结构和链式存储结构。
(6)重点掌握二叉树的基本运算和各种遍历算法的实现。
(7)掌握线索二叉树的概念和相关算法的实现。
(8)掌握哈夫曼树的定义、哈夫曼树的构造过程和哈夫曼编码的产生方法。
(9)掌握并查集的相关概念和算法。
(10)灵活运用二叉树这种数据结构解决一些综合应用问题。
二、实验内容注:二叉树b 为如图7-123所示的一棵二叉树图7-123+实验7.1 编写一个程序algo7-1.cpp,实现二叉树的各种运算,并在此基础上设计一个程序exp7-1.cpp 完成如下功能:(1)输出二叉树b ;(2)输出H 节点的左、右孩子节点值; (3)输出二叉树b 的深度; (4)输出二叉树b 的宽度; (5)输出二叉树b 的节点个数;(6)输出二叉树b 的叶子节点个数。
实验7.2设计一个程序exp7-2.cpp,实现二叉树的先序遍历、中序遍历和后序遍历和非递归算法, 以及层次变量里的算法。
并对图7-123所示的二叉树b 给出求解结果。
b+ACF GIKL+NM+E+HdJD₄B臣1607-1.CPPif(b?-HULL)re3P4+;Qu[rear]-p-b;Qu[rear].1no=1;while(reart=front){Front++;b=Qu[front]-P;lnum-Qu[front].1no;if(b->Ichildt=NULL)rpar+t;Qu[rear]-p=b->1child;Qu[rear].Ino-lnun+1;if(D->rch11d?=NULL)1/根结点指针入队//根结点的层次编号为1 1/队列不为空1/队头出队1/左孩子入队1/右孩子入队redr+t;qu[rear]-p=b->rchild;Qu[rear].1no-lnun*1;}}nax-0;lnun-1;i-1;uhile(i<=rear){n=0;whdle(i<=rear ge Qu[1].1no==1num)n+t;it+;Inun-Qu[i].1n0;if(n>max)nax=n;}return max;田1607-1.CPPreturn max;}elsereturn o;口×int Modes(BTNode *D) //求二叉树D的结点个数int nun1,nun2;if(b==NULL)returng,else if(b->ichild==NULL&D->rchild==NULL)return 1;else{num1-Hodes(b->Ichild);num2=Nodes(b->rchild);return(num1+nun2+1);LeafNodes(BINode *D) //求二叉树p的叶子结点个数int num1,num2;1f(D==NULL)return 0;else if(b->1chi1d==NULLc& b->rch11d==NULL)return 1;else{num1-LeafModes(b->lchild);num2=LeafNodes(b->rchild);return(nun1+nun2);int程序执行结果如下:xCProrn FlslirosfViu l SudiollyPrjecslro7 LJebuglFoj7 ex<1)输出二叉树:A<B<D,E<H<J,K<L,M<,N>>>>),C<F,G<,I>>)<2)'H’结点:左孩子为J石孩子为K(3)二叉树b的深度:7<4)二叉树b的宽度:4(5)二叉树b的结点个数:14(6)二叉树b的叶子结点个数:6<?>释放二叉树bPress any key to continue实验7 . 2程序exp7-2.cpp设计如下:坠eTPT-2.EPP#include<stdio.h》winclude<malloc.h>deFn Masie 00typde chr ElemTyetypede sruct nde{ElemType data;stuc node *lclldstruct node rchild;》BTHode;extern vod reaeBNodeBTNode extrn void DispBTHode(BTNodeuoid ProrderBTNode *b)if(b?-NULL)- 回1 / 数据元素1 / 指向左孩子1 / 指向右孩子*eb car *str)xb1 / 先序遍历的递归算法1 / 访问根结点/ / 递归访问左子树1 7 递归访问右子树/ / 根结点入栈//栈不为空时循环/ / 退栈并访问该结点/ / 右孩子入栈{》v oidprintf(*c“,b->data); Preorder(b->lchild); Pre0rder(b->rchild);Preorder1(BTNode *b)BTNode xSt[Maxsize],*p;int top=-1;if(b!-HULL)top++;St[top]-b;uhle (op>-)p-St[top];top--;printf("%c“,p->data);if(p->rchild?-HULL)A约e程p7-2.CPPprintF(”后序逅历序列:\n");printf(" 递归算法=");Postorder(b);printf("\n");printf(“非递归算法:“);Postorder1(b);printf("\n");序执行结果如下:xCAPrograFleicsoftVisal SudlyrjecsProj 2Debuzlroj72ex"二叉树b:A(B(D,ECH<J,K(L,M<,N)>))),C(F,GC.I>))层次遍历序列:A B C D E F G H I J K L M N先序遍历序列:递归算法:A B D E H J K L M N C F G I非归算法:A B D E H J K L M N C F G I中序遍历序列:递归算法: D B J H L K M N E A F C G I非递归算法:D B J H L K M N E A F C G I后序遍历序列:递归算法: D J L N M K H E B F I G C A非递归算法:D J L N H K H E B F I G C APress any key to continue臼p7-3.CPP15Pp a t h[p a t h l e n]-b->d a t a;//将当前结点放入路径中p a t h l e n t+;/7路任长度培1Al1Path1(b->ichild,patn,pathlen);1/递归扫描左子树Al1Path1(b->rchild,path,pathlen); //递归扫描右子树pathlen-- ; //恢复环境uoid Longpath(BTNode *b,Elemtype path[1,int pathlen,Elemtype longpath[],int elongpatnien) int i;1f(b==NULL){if(pathlen>longpatnlen) //若当前路径更长,将路径保存在1ongpatn中for(i-pathlen-1;i>-8;i--)longpath[i]=path[1];longpathlen-pathlen;elsepath[pathlen]=b->data; pathlen4; //将当前结点放入路径中//路径长度增1iongPath(b->lchild,path₇pathlen,langpath,longpathien);//递归扫描左子树LongPath(b->rchiid,path,pathien,longpath,longpathien);//递归扫描石子树pathlen--; /7饮其环境oid DispLeaf(BTNode xb)- 口凶uoid DispLeaf(BTNode xb)iE(D!=NULL){ if(b->1child--HULL B& b->rchild--HULL)printf("3c“,b->data);elsepispLeaf(b->ichild);DispLeaf(b->rchild);oid nain()8TNodexb;ElenType patn[Maxsize],longpath[Maxsize];int i.longpathien-U;CreateBTNode(b,"A(B(D,E(H(J,K(L,H(,N))))),C(F,G(,I)))");printf("\n二灾树b:");DispBTNode(b);printf("\n\n*);printf(”b的叶子结点:");DispLeaf(b);printf("\n\n");printf("A11Path:");A11Path(b);printf("m");printf("AiiPath1:n");AliPath1(b.path.);printf("");LongPath(b,path,8,longpath,longpathlen);printf(”第一条量长路径长度=d\n”,longpathlen);printf(”"第一茶最长路径:");for(i=longpathlen;i>=0;i--)printf("c",longpatn[1]);printf("\n\n");。
数据结构实验报告 二叉树
数据结构实验报告二叉树数据结构实验报告:二叉树引言:数据结构是计算机科学中的重要基础,它为我们提供了存储和组织数据的方式。
二叉树作为一种常见的数据结构,广泛应用于各个领域。
本次实验旨在通过实践,深入理解二叉树的概念、性质和操作。
一、二叉树的定义与性质1.1 定义二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树可以为空树,也可以是由根节点和左右子树组成的非空树。
1.2 基本性质(1)每个节点最多有两个子节点;(2)左子树和右子树是有顺序的,不能颠倒;(3)二叉树的子树仍然是二叉树。
二、二叉树的遍历2.1 前序遍历前序遍历是指首先访问根节点,然后按照先左后右的顺序遍历左右子树。
在实际应用中,前序遍历常用于复制一颗二叉树或创建二叉树的副本。
2.2 中序遍历中序遍历是指按照先左后根再右的顺序遍历二叉树。
中序遍历的结果是一个有序序列,因此在二叉搜索树中特别有用。
2.3 后序遍历后序遍历是指按照先左后右再根的顺序遍历二叉树。
后序遍历常用于计算二叉树的表达式或释放二叉树的内存。
三、二叉树的实现与应用3.1 二叉树的存储结构二叉树的存储可以使用链式存储或顺序存储。
链式存储使用节点指针连接各个节点,而顺序存储则使用数组来表示二叉树。
3.2 二叉树的应用(1)二叉搜索树:二叉搜索树是一种特殊的二叉树,它的左子树上的节点都小于根节点,右子树上的节点都大于根节点。
二叉搜索树常用于实现查找、插入和删除等操作。
(2)堆:堆是一种特殊的二叉树,它满足堆序性质。
堆常用于实现优先队列,如操作系统中的进程调度。
(3)哈夫曼树:哈夫曼树是一种带权路径最短的二叉树,常用于数据压缩和编码。
四、实验结果与总结通过本次实验,我成功实现了二叉树的基本操作,包括创建二叉树、遍历二叉树和查找节点等。
在实践中,我进一步理解了二叉树的定义、性质和应用。
二叉树作为一种重要的数据结构,在计算机科学中有着广泛的应用,对于提高算法效率和解决实际问题具有重要意义。
二叉树的储存结构的实现及应用
二叉树的储存结构的实现及应用二叉树是一种常见的数据结构,它在计算机科学和算法设计中广泛应用。
二叉树的储存结构有多种实现方式,包括顺序储存结构和链式储存结构。
本文将从这两种储存结构的实现和应用角度进行详细介绍,以便读者更好地理解二叉树的储存结构及其在实际应用中的作用。
一、顺序储存结构的实现及应用顺序储存结构是将二叉树的节点按照从上到下、从左到右的顺序依次存储在一维数组中。
通常采用数组来实现顺序储存结构,数组的下标和节点的位置之间存在一定的对应关系,通过数学计算可以快速找到节点的父节点、左孩子和右孩子。
顺序储存结构的实现相对简单,利用数组的特性可以迅速随机访问节点,适用于完全二叉树。
1.1 实现过程在采用顺序储存结构的实现中,需要首先确定二叉树的深度,然后根据深度确定数组的长度。
通过数学计算可以得到节点间的位置关系,初始化数组并按照规定的顺序将二叉树节点逐一填入数组中。
在访问二叉树节点时,可以通过计算得到节点的父节点和子节点的位置,从而实现随机访问。
1.2 应用场景顺序储存结构适用于完全二叉树的储存和遍历,常见的应用场景包括二叉堆和哈夫曼树。
二叉堆是一种特殊的二叉树,顺序储存结构可以方便地实现它的插入、删除和调整操作,因此在堆排序、优先队列等算法中得到广泛应用。
哈夫曼树则是数据压缩领域的重要应用,通过顺序储存结构可以有效地构建和处理哈夫曼树,实现压缩编码和解码操作。
二、链式储存结构的实现及应用链式储存结构是通过指针将二叉树的节点连接起来,形成一个类似链表的结构。
每个节点包含数据域和指针域,指针域指向节点的左右孩子节点。
链式储存结构的实现相对灵活,适用于任意形态的二叉树,但需要额外的指针空间来存储节点的地址信息。
2.1 实现过程在链式储存结构的实现中,每个节点需要定义为一个包含数据域和指针域的结构体或类。
通过指针来连接各个节点,形成一个二叉树的结构。
在树的遍历和操作中,可以通过指针的操作来实现节点的访问和处理,具有较高的灵活性和可扩展性。
c语言实现二叉树的四种遍历和求深度与叶子个数
c语言实现二叉树的四种遍历和求深度与叶子个数二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。
在C语言中,我们可以使用指针来实现二叉树的操作。
本文将介绍四种常见的二叉树遍历方式,以及如何求解二叉树的深度和叶子节点个数。
首先,我们需要定义一个二叉树节点的结构体,包含一个数据域和两个指针域,分别指向左子节点和右子节点。
代码如下:```cstruct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;};```接下来,我们可以实现二叉树的四种遍历方式:前序遍历、中序遍历、后序遍历和层序遍历。
前序遍历是指先访问根节点,然后递归地遍历左子树和右子树。
代码如下:```cvoid preorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}printf("%d ", root->data);preorderTraversal(root->left);preorderTraversal(root->right);}```中序遍历是指先递归地遍历左子树,然后访问根节点,最后递归地遍历右子树。
代码如下:```cvoid inorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}inorderTraversal(root->left);printf("%d ", root->data);inorderTraversal(root->right);}```后序遍历是指先递归地遍历左子树和右子树,最后访问根节点。
代码如下:```cvoid postorderTraversal(struct TreeNode* root) {if (root == NULL) {return;}postorderTraversal(root->left);postorderTraversal(root->right);printf("%d ", root->data);}```层序遍历是按照树的层次逐层遍历节点。
数据结构实验报告—二叉树
数据结构实验报告—二叉树数据结构实验报告—二叉树引言二叉树是一种常用的数据结构,它由节点和边构成,每个节点最多有两个子节点。
在本次实验中,我们将对二叉树的基本结构和基本操作进行实现和测试,并深入了解它的特性和应用。
实验目的1. 掌握二叉树的基本概念和特性2. 熟练掌握二叉树的基本操作,包括创建、遍历和查找等3. 了解二叉树在实际应用中的使用场景实验内容1. 二叉树的定义和存储结构:我们将首先学习二叉树的定义,并实现二叉树的存储结构,包括节点的定义和节点指针的表示方法。
2. 二叉树的创建和初始化:我们将实现二叉树的创建和初始化操作,以便后续操作和测试使用。
3. 二叉树的遍历:我们将实现二叉树的前序、中序和后序遍历算法,并测试其正确性和效率。
4. 二叉树的查找:我们将实现二叉树的查找操作,包括查找节点和查找最大值、最小值等。
5. 二叉树的应用:我们将探讨二叉树在实际应用中的使用场景,如哈夫曼编码、二叉搜索树等。
二叉树的定义和存储结构二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。
节点被表示为一个由数据和指向其左右子节点的指针组成的结构。
二叉树可以分为三类:满二叉树、完全二叉树和非完全二叉树。
二叉树可以用链式存储结构或顺序存储结构表示。
- 链式存储结构:采用节点定义和指针表示法,通过将节点起来形成一个树状结构来表示二叉树。
- 顺序存储结构:采用数组存储节点信息,通过计算节点在数组中的位置来进行访问和操作。
二叉树的创建和初始化二叉树的创建和初始化是二叉树操作中的基础部分。
我们可以通过手动输入或读取外部文件中的数据来创建二叉树。
对于链式存储结构,我们需要自定义节点和指针,并通过节点的方式来构建二叉树。
对于顺序存储结构,我们需要定义数组和索引,通过索引计算来定位节点的位置。
一般来说,初始化一个二叉树可以使用以下步骤:1. 创建树根节点,并赋初值。
2. 创建子节点,并到父节点。
3. 重复步骤2,直到创建完整个二叉树。
数据结构二叉树实验报告
数据结构二叉树实验报告二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。
本文将介绍二叉树的定义、基本操作以及一些常见的应用场景。
一、二叉树的定义和基本操作二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。
一个节点的左子节点称为左子树,右子节点称为右子树。
二叉树的示意图如下:```A/ \B C/ \D E```在二叉树中,每个节点可以有零个、一个或两个子节点。
如果一个节点没有子节点,我们称之为叶子节点。
在上面的示例中,节点 D 和 E 是叶子节点。
二叉树的基本操作包括插入节点、删除节点、查找节点和遍历节点。
插入节点操作可以将一个新节点插入到二叉树中的合适位置。
删除节点操作可以将一个指定的节点从二叉树中删除。
查找节点操作可以在二叉树中查找指定的节点。
遍历节点操作可以按照一定的顺序遍历二叉树中的所有节点。
二、二叉树的应用场景二叉树在计算机科学中有着广泛的应用。
下面将介绍一些常见的应用场景。
1. 二叉搜索树二叉搜索树是一种特殊的二叉树,它的每个节点的值都大于其左子树中的节点的值,小于其右子树中的节点的值。
二叉搜索树可以用来实现快速的查找、插入和删除操作。
它在数据库索引、字典等场景中有着重要的应用。
2. 堆堆是一种特殊的二叉树,它的每个节点的值都大于或小于其子节点的值。
堆可以用来实现优先队列,它在任务调度、操作系统中的内存管理等场景中有着重要的应用。
3. 表达式树表达式树是一种用来表示数学表达式的二叉树。
在表达式树中,每个节点可以是操作符或操作数。
表达式树可以用来实现数学表达式的计算,它在编译器、计算器等场景中有着重要的应用。
4. 平衡二叉树平衡二叉树是一种特殊的二叉树,它的左子树和右子树的高度差不超过1。
平衡二叉树可以用来实现高效的查找、插入和删除操作。
它在数据库索引、自平衡搜索树等场景中有着重要的应用。
三、总结二叉树是一种常用的数据结构,它在计算机科学中有着广泛的应用。
本文介绍了二叉树的定义、基本操作以及一些常见的应用场景。
数据结构实验三——二叉树基本操作及运算实验报告
《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为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,失败。
数据结构实验二叉树
实验六:二叉树及其应用一、实验目的树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。
二、问题描述首先,掌握二叉树的各种存储结构和熟悉对二叉树的基本操作。
其次,以二叉树表示算术表达式的基础上,设计一个十进制的四则运算的计算器。
如算术表达式:a+b*(c-d)-e/f三、实验要求如果利用完全二叉树的性质和二叉链表结构建立一棵二叉树,分别计算统计叶子结点的个数。
求二叉树的深度。
十进制的四则运算的计算器可以接收用户来自键盘的输入。
由输入的表达式字符串动态生成算术表达式所对应的二叉树。
自动完成求值运算和输出结果。
四、实验环境PC微机DOS操作系统或Windows 操作系统Turbo C 程序集成环境或Visual C++ 程序集成环境五、实验步骤1、根据二叉树的各种存储结构建立二叉树;2、设计求叶子结点个数算法和树的深度算法;3、根据表达式建立相应的二叉树,生成表达式树的模块;4、根据表达式树,求出表达式值,生成求值模块;5、程序运行效果,测试数据分析算法。
六、测试数据1、输入数据:2.2*(3.1+1.20)-7.5/3正确结果:6.962、输入数据:(1+2)*3+(5+6*7);正确输出:56七、表达式求值由于表达式求值算法较为复杂,所以单独列出来加以分析:1、主要思路:由于操作数是任意的实数,所以必须将原始的中缀表达式中的操作数、操作符以及括号分解出来,并以字符串的形式保存;然后再将其转换为后缀表达式的顺序,后缀表达式可以很容易地利用堆栈计算出表达式的值。
例如有如下的中缀表达式:a+b-c转换成后缀表达式为:ab+c-然后分别按从左到右放入栈中,如果碰到操作符就从栈中弹出两个操作数进行运算,最后再将运算结果放入栈中,依次进行直到表达式结束。
如上述的后缀表达式先将a 和b 放入栈中,然后碰到操作符“+”,则从栈中弹出a 和b 进行a+b 的运算,并将其结果d(假设为d)放入栈中,然后再将c 放入栈中,最后是操作符“-”,所以再弹出d和c 进行d-c 运算,并将其结果再次放入栈中,此时表达式结束,则栈中的元素值就是该表达式最后的运算结果。
【数据结构】二叉树的实现
【数据结构】二叉树的实现//-------------------第一部分-----------------#include <stdio.h>typedef char TElemType;//建立结点typedef struct BiTree{TElemType data;struct BiTree *lchild,*rchild;}BiTree;//-------------------第二部分------------------//1、二叉树的建立:先序建立二叉树,//在创建完成二叉树之后,需要把根节点返回来,设置一个整型的临时变量//设置这个变量的目的就是为了返回根节点BiTree *CreateBiTree(BiTree *BT,int itemp){TElemType ch;BiTree *T1;//先申请一个节点T1 = (BiTree *)malloc(sizeof(BiTree));//如果失败,退出if(!T1)exit(1);//如果输入二叉树元素是“#”,说明这个元素是空的scanf("%c",&ch);if(ch !='#'){//将ch值存入新申请的节点中,新申请的节点,左右子树全为空T1->data = ch;T1->lchild = NULL;T1->rchild = NULL;//如果是根节点(只有一个),将申请的节点赋值给BTif(itemp == 0)BT = T1;//如果是左子树,将申请的节点赋值给BT的左孩子if(itemp == 1)BT->lchild = T1;//如果是右子树,将申请的节点赋值给BT的右孩子if(itemp == 2)BT->rchild = T1;//(2)创建左子树,整型变量为1,代表左子树CreateBiTree(T1,1);//(3)创建右子树,整型变量为2,代表右子树CreateBiTree(T1,2);}//返回根节点return BT;}//2、二叉树的遍历:三种方式:先序遍历、中序遍历、后序遍历//先序遍历口诀:根左右//中序遍历口诀:左根右//后续遍历口诀:左右根//(1)先序遍历二叉树void Pre_OrderTraverse(BiTree *T){//如果树存在if(T != NULL){//先输出根节点printf("%c ",T->data);//再输出左子树Pre_OrderTraverse(T->lchild);//最后输出右子树Pre_OrderTraverse(T->rchild);}}//(2)中序遍历二叉树void In_OrderTraverse(BiTree *T){//如果树存在if(T != NULL){//先遍历左子树In_OrderTraverse(T->lchild);//再输出根节点printf("%c ",T->data);//最后输出右子树In_OrderTraverse(T->rchild);}}//(3)后序遍历二叉树void Post_OrderTraverse(BiTree *T){//如果树存在if(T != NULL){//先输出左子树Post_OrderTraverse(T->lchild);//再输出右子树Post_OrderTraverse(T->rchild);//最后输出根节点printf("%c ",T->data);}}//-----------------------第三部分------------------------void main(){BiTree BT,*T;//1、以先序遍历的方式创建二叉树printf("先序建立二叉树,(每个结点为一个字符,空节点为“#”):\n");T = CreateBiTree(&BT,0);printf("-----------------------创建树成功!-------------------------\n");printf("\n");printf("\n");printf("\n");//2、以先序遍历的方式输出二叉树printf("先序建立二叉树的结果是:\n");Pre_OrderTraverse(T);printf("\n");printf("\n");printf("\n");//3、以中序遍历的方式输出二叉树printf("中序建立二叉树的结果是:\n");In_OrderTraverse(T);printf("\n");printf("\n");printf("\n");//4、以后序遍历的方式输出二叉树printf("后序建立二叉树的结果是:\n");Post_OrderTraverse(T);printf("\n");}。
数据结构二叉树实验报告
数据结构二叉树实验报告1. 引言二叉树是一种常见的数据结构,由节点(Node)和链接(Link)构成。
每个节点最多有两个子节点,分别称为左子节点和右子节点。
二叉树在计算机科学中被广泛应用,例如在搜索算法中,二叉树可以用来快速查找和插入数据。
本实验旨在通过编写二叉树的基本操作来深入理解二叉树的特性和实现方式。
2. 实验内容2.1 二叉树的定义二叉树可以用以下方式定义:class TreeNode:def__init__(self, val):self.val = valself.left =Noneself.right =None每个节点包含一个值和两个指针,分别指向左子节点和右子节点。
根据需求,可以为节点添加其他属性。
2.2 二叉树的基本操作本实验主要涉及以下二叉树的基本操作:•创建二叉树:根据给定的节点值构建二叉树。
•遍历二叉树:将二叉树的节点按照特定顺序访问。
•查找节点:在二叉树中查找特定值的节点。
•插入节点:向二叉树中插入新节点。
•删除节点:从二叉树中删除特定值的节点。
以上操作将在下面章节详细讨论。
3. 实验步骤3.1 创建二叉树二叉树可以通过递归的方式构建。
以创建一个简单的二叉树为例:def create_binary_tree():root = TreeNode(1)root.left = TreeNode(2)root.right = TreeNode(3)root.left.left = TreeNode(4)root.left.right = TreeNode(5)return root以上代码创建了一个二叉树,根节点的值为1,左子节点值为2,右子节点值为3,左子节点的左子节点值为4,左子节点的右子节点值为5。
3.2 遍历二叉树二叉树的遍历方式有多种,包括前序遍历、中序遍历和后序遍历。
以下是三种遍历方式的代码实现:•前序遍历:def preorder_traversal(root):if root:print(root.val)preorder_traversal(root.left)preorder_traversal(root.right)•中序遍历:def inorder_traversal(root):if root:inorder_traversal(root.left)print(root.val)inorder_traversal(root.right)•后序遍历:def postorder_traversal(root):if root:postorder_traversal(root.left)postorder_traversal(root.right)print(root.val)3.3 查找节点在二叉树中查找特定值的节点可以使用递归的方式实现。
二叉树的基本操作与实现实验报告
二叉树的基本操作与实现实验报告二叉树是一种重要的数据结构,在计算机科学领域中被广泛应用。
本实验将介绍二叉树的基本操作与实现,并给出相应的实验报告。
一、引言二叉树是一种特殊的树状结构,每个节点至多有两个子节点。
二叉树有许多重要的特性,如平衡二叉树、二叉树等,应用广泛。
在本实验中,我们将介绍二叉树的基本操作和实现。
二、实验目的1.掌握二叉树的基本概念和特性;2.熟悉二叉树的基本操作,包括创建、插入、删除、遍历等;3.学会使用编程语言实现二叉树的基本操作。
三、实验内容本实验主要包括以下内容:1.二叉树的定义和基本概念;2.二叉树的基本操作,包括创建、插入、删除、遍历等;3.使用编程语言实现二叉树的基本操作;4.测试和验证二叉树的基本操作的正确性。
四、实验步骤1.二叉树的定义和基本概念二叉树是一种树状结构,每个节点至多有两个子节点。
二叉树的每个节点包含一个数据项和指向左子树和右子树的指针。
二叉树的特性有很多,如完全二叉树、平衡二叉树、二叉树等。
2.二叉树的基本操作(1)创建二叉树:可以通过手动输入节点数据来创建二叉树,也可以通过读取文件中的数据来创建二叉树。
(2)插入节点:在指定位置插入一个新节点。
(3)删除节点:删除指定位置的节点。
(4)遍历二叉树:有前序遍历、中序遍历和后序遍历三种遍历方式。
3.使用编程语言实现二叉树的基本操作实现二叉树的基本操作可以使用编程语言来完成。
我们可以定义一个二叉树的结构体,包含节点数据和指向左右子树的指针。
然后根据具体的需求,实现相应的操作函数。
4.测试和验证二叉树的基本操作的正确性在完成二叉树的基本操作后,我们可以编写测试代码来验证操作的正确性。
通过创建二叉树,并进行插入、删除和遍历操作,观察输出结果是否符合预期。
五、实验结果与分析在完成二叉树的基本操作后,我们可以进行测试和验证。
通过输出二叉树的遍历结果,比对预期结果来判断操作是否正确。
同时,我们还可以观察二叉树的结构和特性,如是否满足平衡二叉树或二叉树的条件。
数据结构实验报告-树(二叉树)
实验5:树(二叉树)(采用二叉链表存储)一、实验项目名称二叉树及其应用二、实验目的熟悉二叉树的存储结构的特性以及二叉树的基本操作。
三、实验基本原理之前我们都是学习的线性结构,这次我们就开始学习非线性结构——树。
线性结构中结点间具有唯一前驱、唯一后继关系,而非线性结构中结点的前驱、后继的关系并不具有唯一性。
在树结构中,节点间关系是前驱唯一而后继不唯一,即结点之间是一对多的关系。
直观地看,树结构是具有分支关系的结构(其分叉、分层的特征类似于自然界中的树)。
四、主要仪器设备及耗材Window 11、Dev-C++5.11五、实验步骤1.导入库和预定义2.创建二叉树3.前序遍历4.中序遍历5.后序遍历6.总结点数7.叶子节点数8.树的深度9.树根到叶子的最长路径10.交换所有节点的左右子女11.顺序存储12.显示顺序存储13.测试函数和主函数对二叉树的每一个操作写测试函数,然后在主函数用while+switch-case的方式实现一个带菜单的简易测试程序,代码见“实验完整代码”。
实验完整代码:#include <bits/stdc++.h>using namespace std;#define MAX_TREE_SIZE 100typedef char ElemType;ElemType SqBiTree[MAX_TREE_SIZE];struct BiTNode{ElemType data;BiTNode *l,*r;}*T;void createBiTree(BiTNode *&T){ElemType e;e = getchar();if(e == '\n')return;else if(e == ' ')T = NULL;else{if(!(T = (BiTNode *)malloc(sizeof (BiTNode)))){cout << "内存分配错误!" << endl;exit(0);}T->data = e;createBiTree(T->l);createBiTree(T->r);}}void createBiTree2(BiTNode *T,int u) {if(T){SqBiTree[u] = T->data;createBiTree2(T->l,2 * u + 1);createBiTree2(T->r,2 * u + 2); }}void outputBiTree2(int n){int cnt = 0;for(int i = 0;cnt <= n;i++){cout << SqBiTree[i];if(SqBiTree[i] != ' ')cnt ++;}cout << endl;}void preOrderTraverse(BiTNode *T) {if(T){cout << T->data;preOrderTraverse(T->l);preOrderTraverse(T->r);}}void inOrderTraverse(BiTNode *T) {if(T){inOrderTraverse(T->l);cout << T->data;inOrderTraverse(T->r);}}void beOrderTraverse(BiTNode *T){if(T){beOrderTraverse(T->l);beOrderTraverse(T->r);cout << T->data;}}int sumOfVer(BiTNode *T){if(!T)return 0;return sumOfVer(T->l) + sumOfVer(T->r) + 1;}int sumOfLeaf(BiTNode *T){if(!T)return 0;if(T->l == NULL && T->r == NULL)return 1;return sumOfLeaf(T->l) + sumOfLeaf(T->r);}int depth(BiTNode *T){if(!T)return 0;return max(depth(T->l),depth(T->r)) + 1;}bool LongestPath(int dist,int dist2,vector<ElemType> &ne,BiTNode *T) {if(!T)return false;if(dist2 == dist)return true;if(LongestPath(dist,dist2 + 1,ne,T->l)){ne.push_back(T->l->data);return true;}else if(LongestPath(dist,dist2 + 1,ne,T->r)){ne.push_back(T->r->data);return true;}return false;}void swapVer(BiTNode *&T){if(T){swapVer(T->l);swapVer(T->r);BiTNode *tmp = T->l;T->l = T->r;T->r = tmp;}}//以下是测试程序void test1(){getchar();cout << "请以先序次序输入二叉树结点的值,空结点用空格表示:" << endl; createBiTree(T);cout << "二叉树创建成功!" << endl;}void test2(){cout << "二叉树的前序遍历为:" << endl;preOrderTraverse(T);cout << endl;}void test3(){cout << "二叉树的中序遍历为:" << endl;inOrderTraverse(T);cout << endl;}void test4(){cout << "二叉树的后序遍历为:" << endl;beOrderTraverse(T);cout << endl;}void test5(){cout << "二叉树的总结点数为:" << sumOfVer(T) << endl;}void test6(){cout << "二叉树的叶子结点数为:" << sumOfLeaf(T) << endl; }void test7(){cout << "二叉树的深度为:" << depth(T) << endl;}void test8(){int dist = depth(T);vector<ElemType> ne;cout << "树根到叶子的最长路径:" << endl;LongestPath(dist,1,ne,T);ne.push_back(T->data);reverse(ne.begin(),ne.end());cout << ne[0];for(int i = 1;i < ne.size();i++)cout << "->" << ne[i];cout << endl;}void test9(){swapVer(T);cout << "操作成功!" << endl;}void test10(){memset(SqBiTree,' ',sizeof SqBiTree);createBiTree2(T,0);cout << "操作成功!" << endl;}void test11(){int n = sumOfVer(T);outputBiTree2(n);}int main(){int op = 0;while(op != 12){cout << "-----------------menu--------------------" << endl;cout << "--------------1:创建二叉树--------------" << endl;cout << "--------------2:前序遍历----------------" << endl;cout << "--------------3:中序遍历----------------" << endl;cout << "--------------4:后序遍历----------------" << endl;cout << "--------------5:总结点数----------------" << endl;cout << "--------------6:叶子节点数--------------" << endl;cout << "--------------7:树的深度----------------" << endl;cout << "--------------8:树根到叶子的最长路径----" << endl;cout << "--------------9:交换所有节点左右子女----" << endl;cout << "--------------10:顺序存储---------------" << endl;cout << "--------------11:显示顺序存储-----------" << endl;cout << "--------------12:退出测试程序-----------" << endl;cout << "请输入指令编号:" << endl;if(!(cin >> op)){cin.clear();cin.ignore(INT_MAX,'\n');cout << "请输入整数!" << endl;continue;}switch(op){case 1:test1();break;case 2:test2();break;case 3:test3();break;case 4:test4();break;case 5:test5();break;case 6:test6();break;case 7:test7();break;case 8:test8();break;case 9:test9();break;case 10:test10();break;case 11:test11();break;case 12:cout << "测试结束!" << endl;break;default:cout << "请输入正确的指令编号!" << endl;}}return 0;}六、实验数据及处理结果测试用例:1.创建二叉树(二叉链表形式)2.前序遍历3.中序遍历4.后序遍历5.总结点数6.叶子结点数7.树的深度8.树根到叶子的最长路径9.交换所有左右子女10.顺序存储七、思考讨论题或体会或对改进实验的建议通过这次实验,我掌握了二叉树的顺序存储和链式存储,体会了二叉树的存储结构的特性,掌握了二叉树的树上相关操作。
二叉树基本运算算法的实现
二叉树基本运算算法的实现
二叉树是一种常见的数据结构,基本运算算法包括二叉树的遍历、查找、插入、删除等操作。
下面是这些算法的实现:
1. 二叉树遍历:二叉树遍历有三种方式,分别是前序遍历、中序遍历和后序遍历。
其中,前序遍历先访问根节点,再访问左子树和右子树;中序遍历先访问左子树,再访问根节点和右子树;后序遍历先访问左子树,再访问右子树和根节点。
遍历可以使用递归算法或栈实现。
2. 二叉树查找:二叉树查找可以使用递归算法或循环算法实现。
递归算法通过比较节点值实现查找,如果查找值小于当前节点值,则在左子树中查找,否则在右子树中查找。
循环算法使用二叉树的特性,比较查找值和当前节点值的大小,根据大小关系不断移动到左子树或右子树中进行查找,直到找到目标节点或遍历到叶子节点为止。
3. 二叉树插入:二叉树插入需要先查找到插入位置,然后在该位置插入一个新节点。
插入操作可以使用递归算法或循环算法实现。
4. 二叉树删除:二叉树删除分为三种情况:删除叶子节点、删除只有一个孩子的节点和删除有两个孩子的节点。
删除叶子节点很简单,只需要将其父节点的指针设为NULL即可。
删除只有一个孩子的节点需要将父节点的指针指向该节点的
孩子节点。
删除有两个孩子的节点需要找到该节点的后继节点(或前驱节点),将后继节点的值复制到该节点中,然后删除后继节点。
上述算法的实现需要根据具体的编程语言进行调整和实现。
数据结构二叉树遍历实验报告简版
数据结构二叉树遍历实验报告数据结构二叉树遍历实验报告1. 实验目的本实验旨在通过实现二叉树的前序、中序和后序遍历算法,加深对二叉树遍历的理解,并验证算法的正确性。
2. 实验原理2.1 二叉树二叉树是一种特殊的树状数据结构,它的每个节点最多只能有两个子节点。
二叉树可以为空树,也可以是由根节点、左子树和右子树组成的非空树。
2.2 遍历算法二叉树的遍历算法包括前序遍历、中序遍历和后序遍历。
- 前序遍历:先访问根节点,然后依次递归访问左子树和右子树。
- 中序遍历:先递归访问左子树,然后访问根节点,最后递归访问右子树。
- 后序遍历:先递归访问左子树,然后递归访问右子树,最后访问根节点。
3. 实验过程3.1 数据结构设计首先,我们需要设计表示二叉树的数据结构。
在本次实验中,二叉树的每个节点包含三个成员变量:值、左子节点和右子节点。
我们可以使用面向对象编程语言提供的类来实现。
具体实现如下:```pythonclass TreeNode:def __init__(self, val=0, left=None, right=None): self.val = valself.left = leftself.right = right```3.2 前序遍历算法前序遍历算法的实现主要包括以下步骤:1. 若二叉树为空,则返回空列表。
2. 创建一个栈,用于存储遍历过程中的节点。
3. 将根节点入栈。
4. 循环执行以下步骤,直到栈为空:- 弹出栈顶节点,并将其值添加到结果列表中。
- 若当前节点存在右子节点,则将右子节点压入栈。
- 若当前节点存在左子节点,则将左子节点压入栈。
具体实现如下:```pythondef preorderTraversal(root):if not root:return []stack = []result = []stack.append(root)while stack:node = stack.pop()result.append(node.val)if node.right:stack.append(node.right)if node.left:stack.append(node.left)return result```3.3 中序遍历算法中序遍历算法的实现主要包括以下步骤:1. 若二叉树为空,则返回空列表。
二叉树实现及应用实验报告
二叉树实现及应用实验报告实验名称:二叉树实现及应用实验目的:1. 实现二叉树的创建、插入和删除操作。
2. 学习二叉树的遍历方法,并能够应用于实际问题。
3. 掌握二叉树在数据结构和算法中的一些常用应用。
实验内容:1. 实现二叉树的创建、插入和删除操作,包括二叉树的构造函数、插入函数和删除函数。
2. 学习二叉树的三种遍历方法:前序遍历、中序遍历和后序遍历,并应用于实际问题。
3. 掌握二叉树的一些常用应用,如二叉搜索树、平衡二叉树和哈夫曼树等。
实验步骤:1. 创建二叉树的结构体,包括树节点和树的根节点。
2. 实现二叉树的构造函数,用于创建二叉树的根节点。
3. 实现二叉树的插入函数,用于将元素插入到二叉树中的合适位置。
4. 实现二叉树的删除函数,用于删除二叉树中的指定元素。
5. 学习并实现二叉树的前序遍历、中序遍历和后序遍历函数。
6. 运用二叉树的遍历方法解决实际问题,如查找二叉树中的最大值和最小值。
7. 学习并应用二叉搜索树、平衡二叉树和哈夫曼树等常用二叉树结构。
实验结果:1. 成功创建、插入和删除二叉树中的元素,实现了二叉树的基本操作。
2. 正确实现了二叉树的前序遍历、中序遍历和后序遍历,并能够正确输出遍历结果。
3. 通过二叉树的遍历方法成功解决了实际问题,如查找二叉树中的最大值和最小值。
4. 学习并熟练应用了二叉搜索树、平衡二叉树和哈夫曼树等常用二叉树结构,丰富了对二叉树的理解。
实验分析:1. 二叉树是一种重要的数据结构,具有较好的数据存储和查找性能,广泛应用于计算机科学和算法领域。
2. 通过实验,我们深入了解了二叉树的创建、插入和删除操作,以及前序遍历、中序遍历和后序遍历的原理和应用。
3. 实际问题往往可以转化为二叉树的遍历问题进行求解,通过实验,我们成功应用了二叉树的遍历方法解决了实际问题。
4. 熟练掌握二叉搜索树、平衡二叉树和哈夫曼树的原理和应用,对于提高我们在数据结构和算法方面的设计能力具有重要意义。
数据结构 实验四 二叉树的基本操作
实验四二叉树的基本操作一、实验目的:(1)掌握二叉树的定义和存储表示,学会建立一棵特定二叉树的方法;(2)掌握二叉树的遍历算法(先序、中序、后序遍历算法)的思想;(3)掌握二叉树和叶子数、深度之间的关系及联系。
二、实验内容:构造二叉树,再实现二叉树的先序、中序、后序遍历,最后统计二叉树的叶子数和深度。
三、实验步骤:(一) 需求分析1. 二叉树的建立首先要建立一个二叉链表的结构体,包含根节点和左右子树。
因为树的每一个左右子树又是一颗二叉树,所以用递归的方法来建立其左右子树。
二叉树的遍历是一种把二叉树的每一个节点访问并输出的过程,遍历时根结点与左右孩子的输出顺序构成了不同的遍历方法,这个过程需要按照不同的遍历的方法,先输出根结点还是先输出左右孩子,可以用选择语句来实现。
2.程序的执行命令为:1)构造结点类型,然后创建二叉树。
2)根据提示,从键盘输入各个结点。
3)通过选择一种方式(先序、中序或者后序)遍历。
4)输出结果,结束。
(二)概要设计1.二叉树的二叉链表结点存储类型定义typedef struct Node {DataType data;struct Node *LChild;struct Node *RChild;}BitNode,*BitTree;2.建立如下图所示二叉树:3.本程序包含六个模块1) 主程序模块2)先序遍历模块3)中序遍历模块4)后序遍历模块5)叶子数模块6)深度模块四、测试结果1. 进入演示程序后的显示主界面:请输入二叉树中的元素;先序、中序、后序遍历和叶子数、深度分别输出结果。
2.测试结果以扩展先序遍历序列输入,其中#代表空子树:ABC##DE#G##F### 先序遍历序列为:ABCDEGF中序遍历序列为:CBEGDFA后序遍历序列为:CGEFDBA此二叉树的叶子数为:3此二叉树的深度为:53.程序运行结果截图:五、源代码#include#include//节点声明,数据域、左孩子指针、右孩子指针typedef struct BiTNode{char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;//先序建立二叉树BiTree CreateBiTree(){char ch;BiTree T;scanf("%c",&ch);if(ch=='#')T=NULL;else{T = (BiTree)malloc(sizeof(BiTNode));T->data = ch;T->lchild = CreateBiTree();T->rchild = CreateBiTree();}return T;//返回根节点}//先序遍历void PreOrderTraverse(BiTree T){ if(T){printf("%c",T->data);PreOrderTraverse(T->lchild);PreOrderTraverse(T->rchild);}}//中序遍历void InOrderTraverse(BiTree T){ if(T){InOrderTraverse(T->lchild);printf("%c",T->data);InOrderTraverse(T->rchild);}}//后序遍历void PostOrderTraverse(BiTree T){ if(T){PostOrderTraverse(T->lchild);PostOrderTraverse(T->rchild);printf("%c",T->data);}}//求二叉树的深度int Depth(BiTree T){int dep=0,depl,depr;if(!T) dep=0;else{depl=Depth(T->lchild);depr=Depth(T->rchild);dep=1+(depl>depr?depl:depr);}return dep;}//计算叶子节点数int leef(BiTree T){if(!T)return 0;elseif(T->lchild ==NULL&&T->rchild ==NULL)return 1;elsereturn leef(T->lchild) +leef(T->rchild );}//主函数void main(){BiTree T;printf("请按先序输入序列(其中的“#”表示空)\n\n");T = CreateBiTree();//建立二叉树printf("\n先序遍历结果为:");PreOrderTraverse(T);//先序遍历输出printf("\n\n中序遍历结果为:");InOrderTraverse(T);//中序遍历输出printf("\n\n后序遍历结果为:");PostOrderTraverse(T);//后序遍历输出printf("\n\n二叉树深度为:%d\n",Depth(T)); Depth(T);//计算二叉树深printf("\n叶子节点数为:%d\n\n",leef(T)); leef(T);//计算叶子节点数}。
c语言实现二叉树各种基本运算的算法
c语言实现二叉树各种基本运算的算法二叉树是一种常见的数据结构,可以应用于许多算法和问题中。
在C语言中,我们可以使用指针和结构体来实现二叉树的各种基本运算。
本文将详细介绍二叉树的创建、插入、删除、查找以及遍历等基本操作的算法。
1.创建二叉树创建二叉树可以通过递归的方式来实现。
首先定义一个表示二叉树节点的结构体,包含一个值和左右子节点指针。
然后,通过递归地创建左右子树来构建整个二叉树。
```ctypedef struct TreeNode {int data;struct TreeNode* left;struct TreeNode* right;} TreeNode;//创建二叉树TreeNode* createBinaryTree() {int data;scanf("%d", &data);if (data == -1) { // -1表示空节点return NULL;}TreeNode* node = (TreeNode*)malloc(sizeof(TreeNode)); node->data = data;node->left = createBinaryTree();node->right = createBinaryTree();return node;}```2.插入节点在二叉树中插入节点可以按照二叉搜索树的性质进行。
如果要插入的值小于当前节点的值,则将其插入到左子树中,否则插入到右子树中。
如果子树为空,则直接创建一个新节点作为子树。
```c//插入节点TreeNode* insertNode(TreeNode* root, int data) {if (root == NULL) {TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));newNode->data = data;newNode->left = NULL;newNode->right = NULL;return newNode;}if (data < root->data) {root->left = insertNode(root->left, data);} else {root->right = insertNode(root->right, data);}return root;}```3.删除节点删除二叉树中的节点可以分为三种情况:删除叶子节点、删除只有一个子节点的节点、删除有两个子节点的节点。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
《数据结构》实验报告题目:_学号:_________姓名:___________东南大学成贤学院计算机系实验题目一、实验目的1.掌握二叉树的基本操作,理解递归算法。
二、实验内容1.将下图所示二叉树采用二叉链表进行存储,然后进行各种操作测试。
三、实验步骤1.启动VC6.0:开始菜单→程序→Microsoft Visual Studio 6.0 →Microsoft Visual C++ 6.02.建立工程:文件(File)→新建(new)→在弹出的对话框中选择工程标签(Project)→选中选项:Win32 Console Application(不能选别的)→输入工程名(Project Name)→选择工程的存放位置(Location)→单击“确定”按钮(OK)→在弹出的对话框中选中选项:An Empty Project→单击“完成”按钮(Finish)→在弹出的对话框中单击“确定”按钮( OK )。
3.创建头文件:文件(File)→新建(new)→在弹出的对话框中选择文件标签(Files)→选中选项:C/C++ Header File→输入头文件名(此处定义为“bin_tree_node.h”)→单击“确定”按钮(OK)。
bin_tree_node.h内容如下:// 二叉树结点类模板template <class ElemType>struct BinTreeNode{// 数据成员:ElemType data; // 数据域BinTreeNode<ElemType> *leftChild; // 左孩子BinTreeNode<ElemType> *rightChild; // 右孩子};4.创建头文件:文件(File)→新建(new)→在弹出的对话框中选择文件标签(Files)→选中选项:C/C++ Header File→输入头文件名(此处定义为“binary_tree.h”)→单击“确定”按钮(OK)。
binary_tree.h 定义了链队的类模板,代码如下:#ifndef __BINNARY_TREE_H__#define __BINNARY_TREE_H__// 二叉树类模板template <class ElemType>class BinaryTree{private:// 二叉树的数据成员:BinTreeNode<ElemType> *root;// 二叉树的私有函数:void PreOrderHelp(BinTreeNode<ElemType> *r); // 先序遍历void InOrderHelp(BinTreeNode<ElemType> *r); // 中序遍历void PostOrderHelp(BinTreeNode<ElemType> *r);// 后序遍历void Creat(BinTreeNode<ElemType> *r,int flag, ElemType empty, ElemType end);//递归创建子树BinTreeNode<ElemType> *GetRoot(); //返回根指针BinTreeNode<ElemType> *Locate(BinTreeNode<ElemType> *r, ElemType e); //查找元素值为e的结点,返回指针.BinTreeNode<ElemType>* LeftChild(ElemType e);//定位指定元素的左孩子,返回其指针。
BinTreeNode<ElemType>* Parent(BinTreeNode<ElemType>*r, ElemType e); //定位指定元素的父结点BinTreeNode<ElemType>* LeftSibling(ElemType e);//定位指定元素的左兄弟int Size(BinTreeNode<ElemType> *r);int Depth(BinTreeNode<ElemType> *r);int Leaf(BinTreeNode<ElemType> *r); //统计并返回叶子结点个数void Clear(BinTreeNode<ElemType> *r);void DisplayTreeeHelp(BinTreeNode<ElemType> *r, int level);// 按树状形式显示以r为根的二叉树,level为层次数,可设根结点的层次数为1public:// 二叉树公共方法声明:BinaryTree( );// 无参数的构造函数模板void CreateBiTree();// 构造二叉树BinTreeNode<ElemType> *GetRoot();// 返回二叉树的根void InOrder(); // 二叉树的中序遍历void PreOrder(); // 二叉树的先序遍历void PostOrder(); // 二叉树的后序遍历void LevelOrder(); //按层遍历int Locate(ElemType e); //查找元素值为e的结点。
int GetLeft(ElemType e, ElemType &c);//读取指定元素的左孩子int GetParent(ElemType e, ElemType &f);//读取指定元素的父元素int GetLeftSibling(ElemType e, ElemType &s);//读取指定元素的左兄弟int InsertChild(ElemType e,ElemType x,ElemType y);//为指定元素 e 插入左、右孩子int SetElem(ElemType e, ElemType x);//更新指定元素int Size( );int Depth( );int Leaf( ); //统计并返回叶子结点个数virtual ~BinaryTree();// 销毁二叉树void DisplayTree();};函数实现由学生自己完成#endif5. 创建源程序文件main.cpp:文件(File)→新建(new)→在弹出的对话框中选择文件标签(Files)→选中选项:C++ Source File→输入源程序文件名(main)→单击“确定”按钮(OK)。
main.cpp文件内容如下:#include "binary_tree.h" // 二叉树类int main(void){利用swtich构造菜单,对二叉树操作进行测试。
(初始化,构造二叉树,图形显示,前序,中序,后序遍历结果,求结点个数,二叉树深度,叶子结点树,查找结点,找指定结点的左孩子,双亲,左兄弟,插入新的左、右孩子。
}注意:1.在编程过程中注意及时保存编写内容。
四、实验结果1.binary_tree.h的代码2.main.cpp的代码3.运行结果截图(可以有多张)1、binary_tree.h#pragma once#include ”stdafx.h”using namespace std;// 二叉树类模板template <class ElemType>class BinaryTree{private:// 二叉树的数据成员:BinTreeNode<ElemType> *root;// 二叉树的私有函数:void PreOrderHelp(BinTreeNode<ElemType> *r); // 先序遍历void InOrderHelp(BinTreeNode<ElemType> *r); // 中序遍历void PostOrderHelp(BinTreeNode<ElemType> *r);// 后序遍历void Creat(BinTreeNode<ElemType> *r,int flag, ElemType empty, ElemType end);//递归创建子树BinTreeNode<ElemType> *GetRoot(); //返回根指针BinTreeNode<ElemType> *Locate(BinTreeNode<ElemType> *r, ElemType e); //查找元素值为e的结点,返回指针.BinTreeNode<ElemType>* LeftChild(ElemType e);//定位指定元素的左孩子,返回其指针。
BinTreeNode<ElemType>* Parent(BinTreeNode<ElemType>*r, ElemType e); //定位指定元素的父结点BinTreeNode<ElemType>* LeftSibling(ElemType e);//定位指定元素的左兄弟int Size(BinTreeNode<ElemType> *r);int Depth(BinTreeNode<ElemType> *r);int Leaf(BinTreeNode<ElemType> *r); //统计并返回叶子结点个数void Clear(BinTreeNode<ElemType> *r);void DisplayTreeeHelp(BinTreeNode<ElemType> *r, int level);// 按树状形式显示以r为根的二叉树,level为层次数,可设根结点的层次数为1int size;public:// 二叉树公共方法声明:BinaryTree(); // 无参数的构造函数模板void CreateBiTree();// 构造二叉树//BinTreeNode<ElemType> *GetRoot(); // 返回二叉树的根void InOrder(); // 二叉树的中序遍历void PreOrder(); // 二叉树的先序遍历void PostOrder(); // 二叉树的后序遍历void LevelOrder(); //按层遍历int Locate(ElemType e); //查找元素值为e的结点。
int GetLeft(ElemType e, ElemType &c);//读取指定元素的左孩子int GetParent(ElemType e, ElemType &f);//读取指定元素的父元素int GetLeftSibling(ElemType e, ElemType &s);//读取指定元素的左兄弟int InsertChild(ElemType e, ElemType x, ElemType y);//为指定元素 e 插入左、右孩子int SetElem(ElemType e, ElemType x);//更新指定元素int Size();int Depth();int Leaf(); //统计并返回叶子结点个数virtual ~BinaryTree();// 销毁二叉树void DisplayTree();};template <class ElemType>void BinaryTree<ElemType>::PreOrderHelp(BinTreeNode<ElemType> *r) // private{if (r != NULL){cout << r->data << " "; // 访问根结点PreOrderHelp(r->leftChild); // 遍历左子树PreOrderHelp(r->rightChild); // 遍历右子树}}template <class ElemType>void BinaryTree<ElemType>::PreOrder() // public{PreOrderHelp(root);}template <class ElemType>void BinaryTree<ElemType>::InOrderHelp(BinTreeNode<ElemType> *r) // private{if (r != NULL){InOrderHelp(r->leftChild); // 遍历左子树cout << r->data << " "; // 访问根结点InOrderHelp(r->rightChild); // 遍历右子树}}template <class ElemType>void BinaryTree<ElemType>::InOrder() // public{InOrderHelp(root);}template <class ElemType>void BinaryTree<ElemType>::PostOrderHelp(BinTreeNode<ElemType> *r) // private{if (r != NULL){PostOrderHelp(r->leftChild); // 遍历左子树PostOrderHelp(r->rightChild); // 遍历右子树cout << r->data << " "; // 访问根结点}}template <class ElemType>void BinaryTree<ElemType>::PostOrder() // public{PostOrderHelp(root);}template <class ElemType>void BinaryTree<ElemType>::LevelOrder(){LinkQueue<BinTreeNode<ElemType> *> q;BinTreeNode<ElemType> *t = root;if (t != NULL) q.InQueue(t); // 如果根非空,则入队while (!q.Empty()){q.OutQueue(t);cout << t->data << " "; //if (t->leftChild != NULL) // 左孩子非空q.InQueue(t->leftChild); // 左孩子入队if (t->rightChild != NULL) // 右孩子非空q.InQueue(t->rightChild); // 右孩子入队}}template <class ElemType>BinaryTree<ElemType>::BinaryTree(){root = NULL;}template <class ElemType>void BinaryTree<ElemType>::CreateBiTree(){BinTreeNode<ElemType>* r;ElemType end, empty, x;cout <<"按先序序列的顺序输入一棵二叉树"<< endl;cout <<"输入的结束标志是:";cin >> end;cout <<"输入的空结点标志是:";cin >> empty;cout <<"请开始输入:"<< endl;cin >> x;r = new BinTreeNode<ElemType>;r->data = x;r->leftChild = r->rightChild = NULL;root = r;Creat(r, 0, empty, end); //创建根结点的左子树Creat(r, 1, empty, end); //创建根结点的右子树}template <class ElemType>void BinaryTree<ElemType>::Creat(BinTreeNode<ElemType> *r,int flag, ElemType empty, ElemType end){BinTreeNode<ElemType> *p; ElemType x;cin >> x;if (x != end&&x != empty){p = new BinTreeNode<ElemType>; p->data = x;p->leftChild = p->rightChild = NULL;if (flag == 0) r->leftChild = p; //p为左子树else r->rightChild = p; //p为右子树size++;Creat(p, 0, empty, end); //递归创建左子树Creat(p, 1, empty, end); //递归创建右子树}}template <class ElemType>BinTreeNode<ElemType>*BinaryTree<ElemType>::GetRoot(){return root;}template <class ElemType>BinTreeNode<ElemType>*BinaryTree<ElemType>::Locate(BinTreeNode<ElemType> *r, ElemType e) //private{if (r == NULL) return NULL;if (r->data == e) return r;BinTreeNode<ElemType> *p = Locate(r->leftChild, e);if (p == NULL) p = Locate(r->rightChild, e);return p;}template <class ElemType>int BinaryTree<ElemType>::Locate(ElemType e) //public{if (Locate(root, e) == NULL)return false;elsereturn true;}template <class ElemType>BinTreeNode<ElemType>*BinaryTree<ElemType>::LeftChild(ElemType e) //private{BinTreeNode<ElemType>* ep = Locate(root, e);if (ep == NULL) return NULL; //找不到结点eif (ep->leftChild == NULL) //e无左孩子return NULL;return ep->leftChild; //返回e左孩子的指针}template <class ElemType>int BinaryTree<ElemType>::GetLeft(ElemType e, ElemType &c) //Public{BinTreeNode<ElemType>* p = LeftChild(e);if (p == NULL) return false; //e无左孩子c = p->data;return true;}template <class ElemType>BinTreeNode<ElemType>* BinaryTree<ElemType>::Parent(BinTreeNode<ElemType>*r, ElemType e) //private{BinTreeNode<ElemType>* p;if (r == NULL)return NULL;if ((r->leftChild != NULL&&r->leftChild->data == e) ||(r->rightChild != NULL&&r->rightChild->data == e))return r; //r是e的父结点,返回结点r的指针p = Parent(r->leftChild, e); //递归调用r的左子树if (p == NULL) p = Parent(r->rightChild, e);return p;}template <class ElemType>int BinaryTree<ElemType>::GetParent(ElemType e, ElemType &f) //public {if (root == NULL || root->data == e)return false;BinTreeNode<ElemType> *p = Parent(root, e);if (p == NULL) return false; //树中无元素ef = p->data;return true;}template <class ElemType>BinTreeNode<ElemType>* BinaryTree<ElemType>::LeftSibling(ElemType e) //private{if (root->data == e) return NULL;BinTreeNode<ElemType> *p = Parent(root, e);if (p == NULL)return NULL; //无e结点if (p->leftChild->data == e) //e是其父亲的左孩子return NULL;return p->leftChild; //返回e的左兄弟指针}template <class ElemType>int BinaryTree<ElemType>::GetLeftSibling(ElemType e, ElemType &s){if (root->data == e)return false; //根结点无兄弟BinTreeNode<ElemType> *p = LeftSibling(e);if (p == NULL)return false; //e无左兄弟s = p->data;return true;}template <class ElemType>int BinaryTree<ElemType>::InsertChild(ElemType e, ElemType x, ElemType y){BinTreeNode<ElemType> *ep, *xp, *yp;ep = Locate(root, e); //定位元素eif (ep == NULL) return false; //找不到元素exp = new BinTreeNode<ElemType>;xp->data = x;xp->rightChild = NULL;yp = new BinTreeNode<ElemType>;yp->data = y;yp->leftChild = NULL;xp->leftChild = ep->leftChild;ep->leftChild = xp; //结点x置为结点e的左孩子yp->rightChild = ep->rightChild;ep->rightChild = yp; //结点y置为结点e的右孩子size = size + 2;return true;}template <class ElemType>int BinaryTree<ElemType>::SetElem(ElemType e, ElemType x){BinTreeNode<ElemType> *p = Locate(root, e);if (p == NULL) return false;p->data = x;return true;}template <class ElemType>int BinaryTree<ElemType>::Size() //public{return Size(root);}template <class ElemType>int BinaryTree<ElemType>::Size(BinTreeNode<ElemType> *r) //private{if (r == NULL) return 0;elsereturn Size(r->leftChild) + Size(r->rightChild) + 1;//二叉树的结点总数为左右子树的结点数之和加1}template <class ElemType>int BinaryTree<ElemType>::Depth() //public{return Depth(root);}template <class ElemType>int BinaryTree<ElemType>::Depth(BinTreeNode<ElemType> *r) //privateif (r == NULL) return 0;else{int leftD, rightD;leftD = Depth(r->leftChild);rightD = Depth(r->rightChild);return 1 + (leftD > rightD ? leftD : rightD); //二叉树的深度为左右子树的深度的最大值加1}}template <class ElemType>int BinaryTree<ElemType>::Leaf() //public{return Leaf(root);}template <class ElemType>int BinaryTree<ElemType>::Leaf(BinTreeNode<ElemType> *r) //private{if (r == NULL)return 0;if (r->leftChild == NULL&&r->rightChild == NULL)return 1;return Leaf(r->leftChild) + Leaf(r->rightChild);//递归遍历左子树和右子树}template <class ElemType>void BinaryTree<ElemType>::Clear(BinTreeNode<ElemType> *r) //private{if (r != NULL){Clear(r->leftChild); //后序递归Clear(r->rightChild);delete r;size--;}}template <class ElemType>BinaryTree<ElemType>:: ~BinaryTree(){Clear(root);root = NULL;}template <class ElemType>void BinaryTree<ElemType>::DisplayTreeeHelp(BinTreeNode<ElemType> *r, int level)if (r != NULL){DisplayTreeeHelp(r->rightChild, level + 1);//显示右子树cout << endl; //显示新行for (int i = 0; i < level - 1; i++)cout <<" "; //确保在第level列显示结点cout << r->data; //显示结点DisplayTreeeHelp(r->leftChild, level + 1);}}template <class ElemType>void BinaryTree<ElemType>::DisplayTree(){DisplayTreeeHelp(root, 1);cout << endl;}#endif2、stdafx.h#pragma once#include"targetver.h"#include"bin_tree_node.h"#include"lk_queue.h"#include<iostream>#include<cstdlib>3、main.cpp#include"stdafx.h"using namespace std;int main() {BinaryTree<int> bt;int c = 0;int tmp1,tmp2,tmp3;while (c != 15) {cout << endl <<"1. 创建二叉树";cout << endl <<"2. 中序遍历";cout << endl <<"3. 先序遍历";cout << endl <<"4. 后序遍历";cout << endl <<"5. 按层遍历";cout << endl <<"6. 查找节点";cout << endl <<"7. 读取左孩子";cout << endl <<"8. 读取父元素";cout << endl <<"9. 读取左兄弟";cout << endl <<"10. 插入左右孩子";cout << endl <<"11. 更新元素";cout << endl <<"12. 叶子结点个数";cout << endl <<"13. 图形显示";cout << endl <<"14. 销毁二叉树";cout << endl <<"15. 退出";cout << endl <<"选择功能(1~15):";cin >> c;switch (c){case 1:bt.CreateBiTree();break;case 2:bt.InOrder();break;case 3:bt.PreOrder();break;case 4:bt.PostOrder();break;case 5:bt.LevelOrder();break;case 6:cout <<"输入查找节点:";cin >> tmp1;if (bt.Locate(tmp1)) {cout <<"存在";break;}cout <<"不存在";break;case 7:cout <<"输入元素:";cin >> tmp1;if (bt.GetLeft(tmp1,tmp2)) {cout <<"左孩子为:"<< tmp2;break;}cout <<"不存在";case 8:cout <<"输入元素:";cin >> tmp1;if (bt.GetParent(tmp1,tmp2)) {cout <<"父元素为:"<< tmp2;break;}cout <<"不存在";break;case 9:cout <<"输入元素:";cin >> tmp1;if (bt.GetLeftSibling(tmp1,tmp2)) {cout <<"左兄弟为:"<< tmp2;break;}cout <<"不存在";break;case 10:cout <<"输入元素:";cin >> tmp1;cout <<"输入左孩子:";cin >> tmp2;cout <<"输入右孩子:";cin >> tmp3;if (bt.InsertChild(tmp1,tmp2,tmp3)) { cout <<"修改完成" ;break;}cout <<"修改失败";break;case 11:cout <<"输入元素:";cin >> tmp1;cout <<"修改为:";cin >> tmp2;if (bt.SetElem(tmp1, tmp2)) {cout <<"修改成功";break;}cout <<"修改失败";break;case 12:cout <<"叶子结点个数:"<< bt.Leaf();break;case 13:bt.DisplayTree();break;case 14:bt.~BinaryTree();cout <<"销毁成功";break;case 15:exit(0);}}return 0;}。