实验报告二叉树求叶子结点数目(内容清晰)
数据结构二叉树实验报告

一 、实验目的和要求(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.理解二叉树的概念和基本操作。
2.学会使用递归算法实现对二叉树的遍历和操作。
实验内容:给定一个二叉树,求其叶子结点的数目。
实验原理:二叉树是一种常用的数据结构,其所有节点的度不超过2、对于二叉树的遍历,有三种常见的方式:前序遍历、中序遍历和后序遍历。
其中,前序遍历是先访问根节点,然后依次访问左子树和右子树;中序遍历是先访问左子树,然后访问根节点,最后访问右子树;后序遍历是先访问左子树,然后访问右子树,最后访问根节点。
根据二叉树的定义,叶子结点即没有子节点的节点,可以通过递归的方式遍历二叉树来求解叶子结点的数目。
具体操作如下:1. 创建一个变量count,用于记录叶子结点的数目,初始值为0。
2.若当前节点为空,则返回0。
3. 若当前节点没有左子树和右子树,则说明当前节点是叶子结点,count加14. 若当前节点有左子树,则递归调用函数求解左子树的叶子结点数目,并将结果加到count上。
5. 若当前节点有右子树,则递归调用函数求解右子树的叶子结点数目,并将结果加到count上。
6. 返回count作为结果。
实验步骤:1.创建一个二叉树的类,包括节点类和二叉树类,定义根节点和相关操作方法。
2. 在二叉树类中定义一个递归函数countLeafNodes,用于求解叶子结点的数目。
3. 在countLeafNodes函数中实现上述的递归算法。
4.在主函数中创建一个二叉树对象,并插入一些节点。
5. 调用countLeafNodes函数,输出叶子结点的数目。
实验结果:经过测试,结果正确。
实验总结:通过本次实验,我进一步理解了二叉树的概念和基本操作,并学会了使用递归算法实现对二叉树的遍历和操作。
特别是通过实现统计叶子结点数目的功能,我对递归算法有了更深入的理解。
在实验过程中,我也遇到了一些问题,例如如何正确地进行前序遍历,并正确判断叶子结点。
通过查阅资料和与同学的讨论,我逐渐解决了这些问题。
数据结构求二叉树中叶子结点的个数及二叉树的高度

数据结构求二叉树中叶子结点的个数及二叉树的高度二叉树是一种常用的数据结构,它由若干个节点组成,每个节点最多只有两个子节点:左子节点和右子节点。
二叉树常用来表示树状结构,如文件系统、家族关系等等。
本文将介绍如何求二叉树中叶子节点的个数以及二叉树的高度。
一、求二叉树中叶子节点的个数叶子节点是指没有子节点的节点。
要求二叉树中叶子节点的个数,可以使用递归的方法进行计算。
具体步骤如下:1.判断当前节点是否为空,如果为空,则返回0。
2.判断当前节点是否为叶子节点,如果是,则返回13.否则,递归计算当前节点的左子树中叶子节点的个数和右子树中叶子节点的个数,并将它们相加。
下面是一个示例代码:```pythonclass TreeNode:def __init__(self, value):self.val = valueself.left = Noneself.right = Nonedef get_leaf_nodes_count(root):if root is None:return 0if root.left is None and root.right is None:return 1return get_leaf_nodes_count(root.left) +get_leaf_nodes_count(root.right)```二叉树的高度也可以使用递归的方式进行计算。
根据二叉树的定义,二叉树的高度等于左子树的高度和右子树的高度的较大值,再加1、具体步骤如下:1.判断当前节点是否为空,如果为空,则返回0。
2.计算当前节点的左子树的高度和右子树的高度,取较大值。
3.将较大值加1,即得到当前二叉树的高度。
下面是一个示例代码:```pythondef get_tree_height(root):if root is None:return 0left_height = get_tree_height(root.left)right_height = get_tree_height(root.right)return max(left_height, right_height) + 1```综上所述,本文介绍了如何求二叉树中叶子节点的个数和二叉树的高度。
统计二叉树的结点数和叶子结点数的试验报告

统计二叉树的结点数和叶子结点数的试验报告试验报告:统计二叉树的节点数和叶子节点数一、引言二叉树是一种常用的数据结构,它由节点构成,每个节点最多有两个孩子节点。
在实际应用中,经常需要对二叉树进行统计,比如统计其节点数和叶子节点数。
本试验的目的是通过编写算法,实现对二叉树的节点数和叶子节点数的统计,并对此进行详细的测试和分析。
二、设计思想本试验采用递归的方法来统计二叉树的节点数和叶子节点数。
具体思想如下:1.统计节点数:对于任意一个二叉树,其节点数等于左子树的节点数加上右子树的节点数加1(根节点)。
通过递归的方式,可以遍历每个节点,并进行累加。
2.统计叶子节点数:叶子节点是指没有孩子节点的节点,即左右子树均为空。
通过递归的方式,可以遍历每个节点,当遇到叶子节点时,统计数值加一三、实验过程1.设计二叉树数据结构:首先,根据设计思想,我们需要设计一个二叉树的数据结构,并提供相应的操作接口。
这里我们使用C++语言来实现。
2.编写递归算法:在设计好二叉树数据结构后,编写递归算法来统计节点数和叶子节点数。
具体实现思路参考设计思想中的描述,分别统计左子树、右子树和根节点即可。
3.编写测试代码:为了验证算法的正确性,我们需要编写相应的测试代码。
测试代码需要构建不同的二叉树,并分别统计节点数和叶子节点数,然后与预期结果进行对比。
4.运行测试并分析结果:运行测试代码,观察输出结果是否与预期结果一致。
如果不一致,需要检查代码逻辑是否有误,并进行修正。
四、实验结果与分析在设计好二叉树数据结构并编写测试代码后,我们进行了多组测试,并统计了节点数和叶子节点数。
下面以一个测试用例为例,详细分析实验结果。
测试用例:构建二叉树如下:/\23//\456/\78预期结果:节点数:8叶子节点数:4实际结果:节点数:8叶子节点数:4分析:通过对比预期结果和实际结果,可以得出结论,本算法能够正确地统计二叉树的节点数和叶子节点数。
五、总结本试验通过设计二叉树数据结构和编写递归算法,实现了对二叉树的节点数和叶子节点数的统计。
求叶子结点的个数算法

求叶子结点的个数算法叶子结点指的是二叉树中没有子节点的节点,也叫做叶节点。
求叶子结点的个数是二叉树常见的问题,可以通过递归和迭代两种方法来实现。
1.递归算法:递归算法是解决树相关问题的常用方法,可以通过递归遍历二叉树的每个节点,并判断其是否为叶节点。
算法步骤如下:-如果二叉树为空,返回0。
-如果二叉树的左右子树均为空,说明该节点是叶节点,返回1- 递归计算左子树中叶节点的个数,记为leftCount。
- 递归计算右子树中叶节点的个数,记为rightCount。
- 返回leftCount和rightCount之和。
下面是递归算法的示例代码:```pythonclass TreeNode:def __init__(self, val=0, left=None, right=None):self.val = valself.left = leftself.right = rightdef count_leaf_nodes(root):if root is None:return 0if root.left is None and root.right is None:return 1left_count = count_leaf_nodes(root.left)right_count = count_leaf_nodes(root.right)return left_count + right_count```2.迭代算法:迭代算法通过遍历二叉树的节点来统计叶节点的个数,可以借助栈来实现深度优先,或者借助队列来实现广度优先。
算法步骤如下:- 初始化计数器leafCount为0。
-使用一个栈或队列来保存待遍历的节点。
-将根节点压入栈或队列中。
-循环遍历栈或队列,直到为空:- 弹出栈顶或队首的节点,记为current。
- 如果current是叶节点,将leafCount加1- 将current的左右子节点依次压入栈或队列中。
(完整word版)《二叉树基本操作实验报告》

《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算学院:化学与材料科学学院专业班级:09级材料科学与工程系PB0920603姓名:李维谷学号:PB09206285邮箱:liwg@指导教师:贾伯琪实验时间:2010年10月17日一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为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,失败。
树和二叉树实验报告

树和二叉树、实验目的1. 掌握二叉树的结构特征,以及各种存储结构的特点及适用范围。
2. 掌握用指针类型描述、访问和处理二叉树的运算。
、实验要求1. 认真阅读和掌握本实验的程序。
2. 上机运行本程序。
3. 保存和打印出程序的运行结果,并结合程序进行分析。
4. 按照二叉树的操作需要,重新改写主程序并运行,打印出文件清单和运行结果。
、实验内容1. 输入字符序列,建立二叉链表。
2. 按先序、中序和后序遍历二叉树(递归算法)。
3. 按某种形式输出整棵二叉树。
4. 求二叉树的高度。
5. 求二叉树的叶节点个数。
6. 交换二叉树的左右子树。
7. 借助队列实现二叉树的层次遍历。
8. 在主函数中设计一个简单的菜单,分别调试上述算法。
为了实现对二叉树的有关操作,首先要在计算机中建立所需的二叉树。
建立二叉树有各种不同的方法。
一种方法是利用二叉树的性质5来建立二叉树,输入数据时要将节点的序号(按满二叉树编号)和数据同时给出:(序号,数据元素0)。
另一种方法是主教材中介绍的方法,这是一个递归方法,与先序遍历有点相似。
数据的组织是先序的顺序,但是另有特点,当某结点的某孩子为空时以字符“#”来充当,也要输入。
若当前数据不为“#”则申请一个结点存入当前数据。
递归调用建立函数,建立当前结点的左右子树。
四、解题思路1、先序遍历:O访问根结点,G先序遍历左子树,C3先序遍历右子树2、中序遍历:O中序遍历左子树,C2访问根结点,。
中序遍历右子树3、后序遍历:O后序遍历左子树,C2后序遍历右子树,C3访问根结点4、层次遍历算法:采用一个队列q,先将二叉树根结点入队列,然后退队列,输出该结点;若它有左子树,便将左子树根结点入队列;若它有右子树,便将右子树根结点入队列,直到队列空为止。
因为队列的特点是先进后出,所以能够达到按层次遍历二叉树的目的。
五、程序清单#in clude<stdio.h>#in clude<stdlib.h>#defi ne M 100typedef char Etype; //定义二叉树结点值的类型为字符型typedef struct BiTNode {//树结点结构Etype data;struct BiTNode *lch,*rch;}BiTNode,*BiTree;BiTree que[M];int fron t=0,rear=0;//函数原型声明BiTNode *creat_bt1();BiTNode *creat_bt2();void preorder(BiTNode *p);void ino rder(BiTNode *p);void postorder(BiTNode *p);void enq ueue(BiTree);BiTree delqueue();void levorder(BiTree);int treedepth(BiTree);void prtbtree(BiTree,i nt);void excha nge(BiTree);in t leafco un t(BiTree);void pain tleaf(BiTree);BiTNode *t;int coun t=0;//主函数void mai n() {char ch;int k;do{prin tf("\n\n\n");prin tf("\n=================== 主菜单===================");prin tf("\n\n 1.建立二叉树方法1");prin tf("\n\n 2.建立二叉树方法2");prin tf("\n\n 3•先序递归遍历二叉树”);prin tf("\n\n 4•中序递归遍历二叉树”);prin tf("\n\n 5.后序递归遍历二叉树”);printf("\n\n 6.层次遍历二叉树”);prin tf("\n\n 7.计算二叉树的高度”);prin tf("\n\n 8.计算二叉树中叶结点个数”);prin tf("\n\n 9.交换二叉树的左右子树”);printf("\n\n 10.打印二叉树”);printf("\n\n 0.结束程序运行”);prin tf("\n============================================");printf("\n 请输入您的选择(0,1,2,3,4,5,6,7,8,9,10)");sea nf("%d",&k);switch(k){case 1:t=creat_bt1( );break; //调用性质5建立二叉树算法case 2:pri ntf("\n 请输入二叉树各结点值:");fflush(stdi n);t=creat_bt2();break; //调用递归建立二叉树算法case 3:if(t){printf("先序遍历二叉树:");preorder(t);prin tf("\n");}else printf(” 二叉树为空!\n");break;case 4:if(t){printf("中序遍历二叉树:");ino rder(t);prin tf("\n");}else printf("二叉树为空!\n");break;case 5:if(t)postorder(t);{printf("后序遍历二叉树:");prin tf("\n");}else printf(” 二叉树为空!\n");break;case 6:if(t){printf("层次遍历二叉树:");levorder(t);prin tf("\n");}else printf("二叉树为空!\n");break;case 7:if(t){printf("二叉树的高度为:%d",treedepth(t));prin tf("\n");}else printf("二叉树为空!\n");break;case 8:if(t){printf("二叉树的叶子结点数为:%d\n",leafcount(t));prin tf("\n");printf("二叉树的叶结点为:");pai ntleaf(t);else printf(” 二叉树为空!\n");break;case 9:if(t){printf("交换二叉树的左右子树:\n");excha nge(t);prtbtree(t,0);prin tf("\n");}else printf("二叉树为空!\n");break;case 10:if(t){printf("逆时针旋转90度输出的二叉树:\n");prtbtree(t,0);prin tf("\n");}else printf("二叉树为空!\n");break;case 0:exit(0);} //switch}while(k>=1 &&k<=10);printf("\n再见!按回车键,返回… \n");ch=getchar();} //main//利用二叉树性质5,借助一维数组V建立二叉树BiTNode *creat_bt1(){ BiTNode *t,*p,*v[20];i nt i,j;Etype e;/*输入结点的序号i、结点的数据e*/printf("\n请输入二叉树各结点的编号和对应的值(如1,a):");sca nf("%d,%c",&i,&e);while(i!=0&&e!='#') {//当i为0, e为#时,结束循环p=(BiTNode*)malloc(sizeof(BiTNode));p->data=e;p->lch=NULL;p->rch=NULL;v[i]=p;if(i==1)t=p; //序号为1的结点是根else{j=i/2;if(i%2==0)v[j]->lch=p;//序号为偶数,作为左孩子else v[j]_>rch=p; //序号为奇数,作为右孩子}printf("\n请继续输入二叉树各结点的编号和对应的值:”);scan f("%d,%c",&i, &e);}return(t);}//creat_bt1;//模仿先序递归遍历方法,建立二叉树BiTNode *creat_bt2(){BiTNode *t;Etype e;scan f("%c",&e);if(e==' #')t=NULL; //对于#值,不分配新结点else{t=(BiTNode *)malloc(sizeof(BiTNode));t->data=e;t->lch=creat_bt2(); //左孩子获得新指针值t->rch=creat_bt2(); //右孩子获得新指针值return(t);} 〃creat_bt2//先序递归遍历二叉树void preorder(BiTNode *p) {if(P){prin tf("%3c",p->data);preorder(p_>lch);preorder(p->rch);}} //preorder〃中序递归遍历二叉树void ino rder(BiTNode *p){if(p){ino rder(p->lch);prin tf("%3c",p->data);ino rder(p->rch);}} //ino rder//后序递归遍历二叉树void postorder(BiTNode *p){ if(p){ postorder(p->lch);postorder(p->rch);prin tf("%3c",p->data);}} //postorder void enq ueue(BiTree T){if(fron t!=(rear+1)%M){rear=(rear+1)%M;que[rear]=T;}}BiTree delqueue(){if(fron t==rear)return NULL;fron t=(fro nt+1)%M;return(que[fro nt]);}void levorder(BiTree T)//层次遍历二叉树{BiTree p;if(T){enq ueue(T);while(fro nt!=rear){p=delqueue( );prin tf("%3d",p->data);if(p->lch!=NULL)e nqueue(p->lch); if(p->rch!=NULL)e nq ueue(p->rch);}}} int treedepth(BiTree bt){int hl,hr,max;if(bt!=NULL){ hl=treedepth(bt->lch); hr=treedepth(bt->rch);max=(hl>hr)?hl:hr; return (max+1);}else return (0);} void prtbtree(BiTree bt,i nt level)形{int j;if(bt){prtbtree(bt->rch,level+1);for(j=0;j<=6*level;j++)pri ntf(" ”);prin tf("%c\n",bt->data);prtbtree(bt->lch,level+1);}}//计算二叉树的高度〃逆时针旋转90度输出二叉树树void excha nge(BiTree bt) // 交换二叉树左右子树{BiTree p;if(bt){p=bt->lch;bt->lch=bt->rch;bt->rch=p;excha nge(bt->lch);excha nge(bt->rch);}}in t leafcou nt(BiTree bt) // 计算叶结点数{if(bt!=NULL){leafc oun t(bt->lch);leafc oun t(bt->rch);if((bt->lch==NULL) &&(bt->rch==NULL))coun t++;}return(co unt);void pai ntleaf(BiTree bt) // 输出叶结点{if(bt!=NULL) {if(bt->lch==NULL&&bt->rch==NULL)prin tf("%3c",bt->data);pain tleaf(bt->lch);pain tleaf(bt->rch);}}图11.2所示二叉树的输入数据顺序应该是:abd#g###ce#h##f##图11.2 二叉树示意图运行结果:=================王采单1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 1请输入二叉树各结点的编号和对应的值(如1,a):1,a 请继续输入二叉树各结点的编号和对应的值:2,b请继续输入二叉树各结点的编号和对应的值:3,c请继续输入二叉树各结点的编号和对应的值:4,d请继续输入二叉树各结点的编号和对应的值:6,e请继续输入二叉树各结点的编号和对应的值:7,f请继续输入二叉树各结点的编号和对应的值:9,g请继续输入二叉树各结点的编号和对应的值:13,h请继续输入二叉树各结点的编号和对应的值:===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 3先序遍历二叉树:abdgcehf===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 4中序遍历二叉树:dgbaehcf===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23. 先序递归遍历二叉树4. 中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 5后序遍历二叉树:gdbhefca===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 6层次遍历二叉树:97 98 99100101102103104===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 7 二叉树的高度为:4王采单 1. 建立二叉树方法 12. 建立二叉树方法 23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 8 二叉树的叶子结点数为:3二叉树的叶结点为: g h f1. 建立二叉树方法 12. 建立二叉树方法 23. 先序递归遍历二叉树===================王采单"); ”);4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 9交换二叉树的左右子树:dgbaehc===================王采单");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 10 逆时针旋转90度输出的二叉树:dgbaehc王采单”);1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 2请输入二叉树各结点值:abd#g###ce#h##f##===================主菜单===================");1. 建立二叉树方法12. 建立二叉树方法23•先序递归遍历二叉树4•中序递归遍历二叉树5. 后序递归遍历二叉树6. 层次遍历二叉树7. 计算二叉树的高度8. 计算二叉树中叶结点个数9. 交换二叉树的左右子树10. 打印二叉树0.结束程序运行请输入您的选择(0,1,2,3,4,5,6,7,8,9,10) 0请按任意键继续•• •六、调试心得及收获建立二叉树有两种方法:一种方法是利用二叉树的性质5来建立二叉树;另一种方法是主教材中介绍的方法,这是一个递归方法,与先序遍历有点相似。
二叉树实验报告

实验报告实验:树和二叉树一、实验目的:1.掌握二叉树的存储实现2.掌握二叉树的遍历思想3.掌握二叉树的常见算法的程序实现二、实验内容:1.编写函数,输入字符序列,建立二叉树的二叉链表。
2.编写函数,实现二叉树的中序递归遍历算法。
(最好也能实现前缀和后缀遍历算法)3.编写函数,实现二叉树的中序非递归遍历算法。
4.编写函数,借助队列实现二叉树的层次遍历算法。
5.编写函数,求二叉树的高度。
6.编写函数,求二叉树的结点个数。
7.编写函数,求二叉树的叶子个数。
8.编写函数,交换二叉树每个结点的左子树和右子树。
9.编写一个主函数,在主函数中设计一个简单的菜单,分别调试上述算法。
三、方法与步骤:详见源代码。
四、小结:1.注意并理解了递归算法的执行步骤,使得编写程序时比较顺利,而且得到同学的帮助,减少了发生错误的次数,才使得报告能够顺利完成。
2.注意字符类型数据在输入时的处理,使输入没有错误。
3.重点理解利用栈结构实现非递归算法。
五、实验结果:实验报告源代码:#include"stdio.h"#include"malloc.h"#include"math.h"#define maxsize 100typedef struct btnode{char data;struct btnode *lc,*rc;}bitree;bitree *creat_bitree(bitree *p){char a;scanf("%c",&a);if(a!='#'){ p=(bitree *)malloc(sizeof(bitree));p->data=a;p->lc=creat_bitree(p->lc);p->rc=creat_bitree(p->rc);}elsep=NULL;return p;}void print1_bitree1(bitree *p){if(p==NULL)return ;printf("%c",p->data);print1_bitree1(p->lc);print1_bitree1(p->rc);}void print1_bitree2(bitree *p){if(p==NULL)return ;print1_bitree2(p->lc);printf("%c",p->data);print1_bitree2(p->rc);}void print1_bitree3(bitree *p) {if(p==NULL)return ;print1_bitree3(p->lc);print1_bitree3(p->rc);printf("%c",p->data);}int print2_bitree(bitree *p){int top=-1;bitree *a[maxsize];if(p==NULL) return 0;while(p!=NULL||top!=-1){while(p!=NULL){a[++top]=p;p=p->lc;}if(top<0)return 0;else{p=a[top--];printf("%c",p->data);p=p->rc;}}return 1;}int print3_bitree(bitree *p){int front=-1,rear=0;bitree *b[maxsize];if(p==NULL)return 0;b[rear]=p;while(front!=rear){p=b[++front];printf("%c",p->data);if(p->lc!=NULL)b[++rear]=p->lc;if(p->rc!=NULL)b[++rear]=p->rc;}return 1;}int jiedian_bitree(bitree *p,int a){if(p==NULL)return a;a++;a=jiedian_bitree(p->lc,a);a=jiedian_bitree(p->rc,a);return a;}int yezi_bitree(bitree *p){if(p==NULL)return 0;if(p->lc==NULL&&p->rc==NULL)return 1;return (yezi_bitree(p->lc)+yezi_bitree(p->rc)); }int depth(bitree *p){if(!p)return 0;else{int m=depth(p->lc);int n=depth(p->rc);return (m>n?m:n)+1;}}void change(bitree *p){bitree *q;if(!p)return;else{q=p->lc;p->lc=p->rc;p->rc=q;change(p->lc);change(p->rc);}}int main(){int x=8,a=0,i,j=0;bitree *p;p=NULL;while(x==8){printf("建立二叉链树,请输入字符\n");if(j==1){getchar();j=0;}p=creat_bitree(p);x=0;while(x!=8){ printf("***************************************************** *************************\n");printf("1.递归遍历\t2.中序非递归遍历\t3.层次遍历\t\t4.二叉树高度\n5.结点个数\t6.叶子个数\t\t7.交换每个结点左右子树\t8.重建二叉链树\n9.退出\n");scanf("%d",&x);switch(x){case 1:printf("1.先序2.中序3.后序");printf("\n");scanf("%d",&x);if(x==1)print1_bitree1(p);if(x==2)print1_bitree2(p);if(x==3)print1_bitree3(p);break;case 2:print2_bitree(p);break;case 3:print3_bitree(p);break;case 4:i=depth(p);printf("%d",i);break;case 5:a=jiedian_bitree(p,a);printf("%d",a);break;case 6:i=yezi_bitree(p);printf("%d",i);break;case 7:change(p);break;case 8:j=1;break;}if(x==9)break;printf("\n\n");}}return 0;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验叶子结点的计算
姓名:xxx 班级:xxx)
学号:16130xxxxx 时间2017.10.22
1 问题描述
二叉树叶子节点的计算
1.二叉树的创建
2.二叉树的图形显示
3.二叉树叶子节点的计算
2 结构设计
二叉树叶子结点的计算主要是二叉树的创建,在这里选择的存储结构是一个链式存Data lchild rchild
struct BTNode{
int data;
BTNode*lchild;
BTNode*rchild;
};
3 算法设计
在程序正式编写之前我定义了几个功能函数
(1)指针清空函数,预定义一个指针bt 使lchild和rchild的值分别赋予bt并且使其为空
static int clear(BTNode *bt)
{
if (bt)
{
clear(bt->lchild );
clear(bt->rchild );
cout<<"释放了指针"<<bt<<"所指向的空间"<<endl;
delete bt;
}
return 0;
};
(2)叶子结点计数算法
叶子结点的特点是左孩子和右孩子均为空,利用这个特点可以轻松的判断出是否是叶子节点,利用递归算法解决这个问题,预先定义一个计数器count 当所遇结点满足叶子结点的条件时,count+1
static int Leaf(BTNode *p,int&count)
{
if(p)
{
if(p->lchild==NULL&&p->rchild==NULL)count++;
Leaf(p->lchild,count);
Leaf(p->rchild,count);
}
return count;
}
(2)二叉树的创建
同样是利用递归的方式,输入参数包括指针,左右判断,以及判空条件static int create(BTNode *p,int k ,int end)
{
BTNode *q;
int x;
cin>>x;
if(x!=end)
{
q=new BTNode;
q->data =x;
q->lchild=NULL;
q->rchild=NULL;
if(k==1)p->lchild=q;
if(k==2)p->rchild=q;
create(q,1,end);
create(q,2,end);
}
return 0;
};
(3)类的构造函数创建树并且输入各结点数值
在这里,采用的时先序遍历法依次输入树中的各结点数值
Step 1:定义新的结构体指针,
Step 2:申请动态存储空间;
Step 3:输入节点元素,并且指针后移到输入结点的后继结点,end作为结点结束标志;
Step 4:重复步骤3,直到输入结束;
void BinaryTree::CreateBiTree (int end)
{
cout<<"请按照先序序列的顺序输入二叉树,-1为空指针域标志:"<<endl;
BTNode *p;
int x;
cin >>x;
if(x==end)return;
p=new BTNode;
if(!p) {
cout<<"申请内存失败"<<endl;
exit(-1);
}
p->data =x;
p->lchild =NULL;
p->rchild =NULL;
BT=p;
create(p,1,end);
create(p,2,end);
}
(4) 按树形图输出树
Step 1:定义结点bt 计数器level
Step 2:当bt 存在 bt 指向左孩子,level+1换行,输出结点值
Step 3:bt 指向右孩子level+1输出数值,依次递归
void BinaryTree::DisplayBTreeShape (BTNode*bt, int level)
{
if(bt)
{
DisplayBTreeShape(bt->rchild,level+1);
cout<<endl;
for(int i=0;i<level-1;i++)
cout<<" ";
cout<<bt->data;
DisplayBTreeShape(bt->lchild,level+1);
}
}
4程序运行测试
输入该树的先序遍历
1,2,3,(-1,-1),4(-1,-1),5,6(-1.-1)(-1) 5
1
2
5调试记录及收获
调试记录:
(1)在开始编译过程中,,程序编译不通过在case选择中创建被直接跳过,仔细检查过程中,,发现在类的调用过程中缺少了类的主体,在后期其余练习中同样碰到了kidding错误,在后期的解决方法中在论坛上找到了解决方法及出错原因initialization of 'XXX' is skipped by 'case' label 原因及解决办法
原创 2013年08月12日 18:34:05 1461
出错代码段:
switch (t)
{
case 0:
int a = 0;
break;
default:
break;
}
编译时提示:“error C2361: initialization of 'a' is skipped by 'default' label”。
这怎么可能?
出错原因:
C++约定,在块语句中,对象的作用域从对象的声明语句开始直到块语句的结束,也就是说default标号后的语句是可以使用对象a的。
如果程序执行时从switch处跳到default处,就会导致对象a没有被正确地初始化。
确保对象的初始化可是C++的重要设计哲学,所以编译器会很严格地检查这种违例情况,像上述的示例代码中default 语句后面并没有使用a,但考虑到以后代码的改动可能无意中使用,所以一样被封杀。
明白了原因,解决起来就很容易了。
只要明确地限制对象a的作用域就行了。
switch (t)
{
case 0:。