实验报告二叉树求叶子结点数目(内容清晰)
数据结构二叉树实验报告
一 、实验目的和要求(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;}。
数据结构实验报告-树(二叉树)
实验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.顺序存储七、思考讨论题或体会或对改进实验的建议通过这次实验,我掌握了二叉树的顺序存储和链式存储,体会了二叉树的存储结构的特性,掌握了二叉树的树上相关操作。
求二叉树的深度、总结点数和叶子结点数
求⼆叉树的深度、总结点数和叶⼦结点数⼆叉树的⼆叉链表的存储结构:typedef char TElemType;typedef struct BiTNode{TElemType data;//数据元素BiTNode * lchild;//指向左孩⼦BiTNode * rchild;//指向右孩⼦}BiTNode,* BiTree;⼀、⼆叉树的深度如果⼆叉树为空,结点的深度为0;如果⼆叉树只有⼀个结点G为例,其中,它的左右⼦树的深度为0;⽽这种情况⼆叉树的深度为1。
如果⼆叉树有两个结点D,G为例,其中,以D为根结点的⼆叉树的左⼦树的深度为0,右⼦树的深度为(0+1);⽽这种情况⼆叉树的深度为2。
…………如果⼆叉树有n个结点,⼆叉树的深度为⼆叉树左右⼦树深度的最⼤值+1。
代码:int Depth(BiTree T){int m,n;if(!T) return 0;if(!T->lchild && !T->rchild) return 1;else{m = Depth(T->lchild);n = Depth(T->rchild);return 1+(m>n?m:n);}⼆、⼆叉树的叶⼦结点数如果⼆叉树为空,⼆叉树的叶⼦结点数为0;如果⼆叉树只有⼀个结点G(左右⼦树为空)为例,⽽这种情况⼆叉树的叶⼦结点数为1。
如果⼆叉树有两个结点D(右⼦树为⾮空),G(左右⼦树为空)为例,其中,以D为根结点的⼆叉树的左⼦树的叶⼦结点数为0,右⼦树的叶⼦结点数为1;⽽这种情况⼆叉树的叶⼦结点数为1。
…………如果⼆叉树有n个结点,⼆叉树的叶⼦结点数为⼆叉树左右⼦树叶⼦结点数的和。
代码:int CountLeaf(BiTree T){int m,n;if(!T) return 0;if(!T->lchild && !T->rchild) return 1;else{m = CountLeaf(T->lchild);n = CountLeaf(T->rchild);return m+n;}}三、⼆叉树的结点数如果⼆叉树为空,⼆叉树的结点数为0;如果⼆叉树只有⼀个结点G(左右⼦树为空)为例,⽽这种情况⼆叉树的结点数为1。
求二叉树中叶子结点的个数
//bt->lchild == NULL && bt->rchild == NULL
cout<<bt->data;
}
PreOrderPrintLeaf(bt->lchild);
PreOrderPrintLeaf(bt->rchild);
cout<<endl;
cout<<"中序遍历序列为:";
t.InOrder(t.GetRoot());
cout<<endl;
cout<<"后序遍历序列为:";
t.PostOrder(t.GetRoot());
cout<<endl;
cout<<"层序遍历序列为:";
t.LeverOrder(t.GetRoot());
cout<<endl;
cout<<"结点数为:"<<t.CountNode(t.GetRoot())<<endl;
cout<<"叶子结点为:";
t.PreOrderPrintLeaf(t.GetRoot());
cout<<endl;
cout<<"深度为:"<<t.Depth(t.GetRoot())<<endl;
public:
BiTree();
void PreOrder(BiNode<DataType> *bt);
数据结构实验报告(二叉树的基本操作)
else LeafNum=LeafCount(root->LChild)+LeafCount(root->RChild);
//叶子数为左右子树数目之和
return LeafNum;
printf("\n菜单选择\n\n");
printf(" 1.树状输出二叉树2.先序遍历二叉树\n");
printf(" 3.中序遍历二叉树4.后序遍历二叉树\n");
printf(" 5.输出叶子结点6.输出叶子结点的个数\n");
printf(" 7.输出二叉树的深度8.退出\n");
printf("\n----------------------------------------------------------------------\n");
{
printf("\n\n");
j=j+1; k=0;
while(k<nlocate)
{
printf(" ");
k++;
}
}
while(k<(nlocate-1))
{
printf(" ");
k++;
}
printf("%c",bt->data );
q.front=q.front+1;
if(bt->LChild !=NULL)//存在左子树,将左子树根节点入队列
完全二叉树计算叶子结点数
完全⼆叉树计算叶⼦结点数
1. ⾸先看下完全⼆叉树的定义:
⼀棵深度为k,且有个节点称之为满⼆叉树;深度为k,有n个节点的⼆叉树,当且仅当其每⼀个节点都与深度为k的满⼆叉树中,序号为1⾄n的节点对应时,称之为完全⼆叉树。
2.⼀条规则:
对任何⼀棵⼆叉树T,如果其终端结点数为,度为2的结点数为,则。
推导过程:
n0是度为0的结点总数(即叶⼦结点数),n1是度为1的结点总数,n2是度为2的结点总数。
则分⽀数=2n2+n1 (每个n2节点有2个分⽀,每个n1结点有1个分⽀)
另外⼜有:分⽀数=n0+n1+n2-1 (每个结点上⾯对应⼀个分⽀,除了根节点上⾯没有分⽀)
2n2+n1=n0+n1+n2-1 得 n0=n2+1
3.假设n为完全⼆叉树的结点总数,则有:n=n0+n1+n2
结合2的结论有:n0=(n-n1+1)/2
4.由于n1=1或者0,则
当n1=0时(即度为1的节点为0个时,此时n为奇数)或者n为奇数时
n0= (n+1)/2;
当n1=1时(即度为1的节点为1个时,此时n为偶数)或者n为偶数
n0= n/2;。
编写递归算法计算二叉树中叶子结点的数目
学院名称专业班级实验成绩学生姓名学号实验日期课程名称数据结构实验题目 2 树一、实验目的与要求熟悉树的各种表示方法和各种遍历方式,掌握有关算法的实现,了解树在计算机科学及其它工程技术中的应用。
二、主要仪器设备Cfree三、实验内容和原理[问题描述]编写递归算法,计算二叉树中叶子结点的数目。
[输入]一棵二叉树的结点若无子树,则可将其子树看作“.”,输入时,按照前序序列的顺序输入该结点的内容。
对例题中的树,其输入序列ABD..EH...CF.I..G..。
○A○B○C○D○E○F○G○H○I[输出]若为空二叉树,则输出:THIS IS A EMPTY BINARY TREE。
若二叉树不空,输出叶子结点的个数。
[存储结构]采用二叉链表存储[算法的基本思想]采用递归方法建立和遍历二叉树。
首先建立二叉树的根结点,然后建立其左右子树,直到空子树为止。
遍历二叉树,若某一结点的左右孩子均为NULL,则该结点为叶子结点。
[参考源程序]#include <stdio.h>#include<malloc.h>struct node{char info;struct node *llink, *rlink;};typedef struct node NODE;NODE *create(){ //构造二叉树char x;NODE *p;scanf("%c", &x);printf("%c", x); //打印出已输入的二叉树if(x!='.'){p=(NODE *)malloc(sizeof(NODE));p->info=x;p->llink=create();p->rlink=create();}else p=NULL;return p;}int run(NODE *t){static int count=0;if(t){run(t->llink); //递归遍历左子树,直到叶子处run(t->rlink); //递归遍历右子树,直到叶子处if(t->llink ==NULL && t->rlink == NULL) {count++;}}return count;}main(){ NODE *T;int left_number;printf("请输入一棵树:\n" );T=create();printf("\n");if(!T) printf("This is a empty binary tree.");else{left_number=run(T);printf("\n这棵树共有%d 个子叶. \n", left_number);}printf("\n");}四、实验结果与分析(2)习题1:注意叶子结点是指该结点既没有左孩子又没有右孩子,采用递归算法就很容易计算出其数目。
统计二叉树的结点数和叶子结点数的试验报告
实验、实习报告姓名(学号):所在组别:7-1 实验题目:统计二叉树的结点数和叶子结点数实验时间:2014.10.30 实验地点:软件楼一、实验目的深入了解的二叉树的基本操作(二叉树的创建以及统计结点数和叶子结点数)及其运用二、实验内容1.编写一程序,统计出二叉树的结点数和叶子结点数三、实验步骤#include<stdio.h>#include<stdlib.h>#include<iostream>using namespace std;int C=0,C3=0;//二叉链表存储定义typedef struct bitnode{char data;struct bitnode*rchild,*lchild; }bitnode,*bitree;//创建二叉树void createbitree(bitree&T){int i=0,j=0;char e;cin>>e;C=C+1;if(e=='#'){T=NULL;C3=C3+1;}else{T=(bitree)malloc(sizeof(bitnode));T->data=e;createbitree(T->lchild);createbitree(T->rchild);}}//统计二叉树叶子结点int countleaf(bitree&T){int countleft,countright,C2;if(!T)return0;if(T->lchild==NULL&&T->rchild==NULL) {C2=0;return1;}countleft=countleaf(T->lchild);countright=countleaf(T->rchild);C2=countleft+countright;return C2;};//主函数void main(){bitree T;int C1=0,C2;cout<<"请输入二叉树:";createbitree(T);C2=countleaf(T);if(C!=3){C1=C-C2-C3;cout<<"二叉树的结点数:"<<C1<<endl;cout<<"二叉树的叶子结点数:"<<C2<<endl; }else{C1=1;cout<<"二叉树的结点数:"<<C1<<endl;cout<<"二叉树的叶子结点数:"<<C2<<endl; }特殊情况(只有一个根结点存在的):普通情况:五、小组成员参与实验情况表成员角色完成的内容xxx 编写程序xxx 编写程序xxx 编写程序,整理Word六、实验小结通过实验可以增强对二叉树的理解和所学知识的灵活运用,增强自我学习能力和团队的合作精神。
实验报告二叉树求叶子结点数目
实验叶子结点的计算姓名:xxx 班级:xxx)学号:16130xxxxx 时间2017.10.221 问题描述二叉树叶子节点的计算1.二叉树的创建2.二叉树的图形显示3.二叉树叶子节点的计算2 结构设计二叉树叶子结点的计算主要是二叉树的创建,在这里选择的存储结构是一个链式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+1static 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 计数器levelStep 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)在开始编译过程中,,程序编译不通过在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”。
二叉树的叶子结点算法
二叉树的叶子结点算法简介二叉树是一种常见的数据结构,由节点和边组成。
每个节点最多有两个子节点,分别称为左子节点和右子节点。
叶子结点是指没有子节点的节点。
在二叉树中,查找并计算叶子结点的数量是一种常见的算法问题。
本文将介绍二叉树的叶子结点算法,并提供实现示例。
算法原理要计算二叉树中的叶子结点数量,可以使用递归算法。
递归是一种通过调用自身来解决问题的方法。
对于二叉树,可以通过递归地遍历每个节点来计算叶子结点数量。
具体步骤如下: 1. 如果当前节点为空,则返回0。
2. 如果当前节点没有左子节点和右子节点,则返回1。
3. 否则,递归地计算左子树和右子树中的叶子结点数量,并将它们相加。
实现示例下面是一个使用Python语言实现二叉树的叶子结点算法的示例代码:class Node:def __init__(self, value):self.value = valueself.left = Noneself.right = Nonedef count_leaf_nodes(root):if root is None:return 0if root.left is None and root.right is None:return 1left_leaf_nodes = count_leaf_nodes(root.left)right_leaf_nodes = count_leaf_nodes(root.right)return left_leaf_nodes + right_leaf_nodes# 创建一个二叉树root = Node(1)root.left = Node(2)root.right = Node(3)root.left.left = Node(4)root.left.right = Node(5)# 计算叶子结点数量leaf_node_count = count_leaf_nodes(root)print("叶子结点数量为:", leaf_node_count)在上述示例代码中,我们首先定义了一个Node类表示二叉树的节点。
求一棵二叉树的叶结点数
《数据结构》实验报告学号:机器号8 姓名:日期:2011-4-28 程序名:稀疏矩阵的逆置.c、求二叉树叶结点数.c实验内容:(一)将稀疏矩阵A转置为矩阵B(A和B都采用三元组表示)(二)求一棵二叉树的叶结点数一、目的和要求(需求分析):1、了解稀疏矩阵的三元组存储形式。
2、熟悉掌握三元表压缩存储矩阵的转置算法。
3、理解二叉树的定义和性质。
4、掌握二叉树的存储结构和创建方法。
二、程序设计的基本思想,原理和算法描述:(包括程序的结构,数据结构,输入/输出设计,符号名说明等)(一)将稀疏矩阵A转置为矩阵B(A和B都采用三元组表示):采用三元组顺序表形式存储,以函数Triple表示,存储非零元行列坐标和数值,并设置非零元个数最大值为12500。
再定义函数TSMatrix,存储矩阵的行数、列数以及非零元个数。
并将非零元以data[ ]数组形式存储。
在主函数中定义两个矩阵A和B,输入矩阵的行列数并依次输入矩阵非零元的行列坐标及值,经过函数TransposeSMAtrix( )对三元组表A。
data从第一行起整个扫描,A.data以行序存储,经过函数处理后,其对应的值付给B.data,B.data以列序存储。
最后输出结果。
(二)求一棵二叉树的叶结点数:采用二叉树的链式存储表示,构造二叉树T,在T内采用递归方式生成根结点,并且构造左子树和右子树,输入相应的结点数据data,构造完成后返回。
同时又调用递归来实现叶结点计数。
若为空树则返回0,若为叶结点则返回1,若非以上两种则继续递归,直到遍历全部结点,最后输出叶结点树目。
三、调试和运行程序过程中产生的问题及采取的措施:程序名:稀疏矩阵的逆置.c:调试过程基本上还是很顺利的,没有出现什么具体语法和逻辑问题。
[ 源程序] 程序名:求二叉树叶结点数.c在二叉树的构建中,程序出现了比较大的错误。
BiTree CreateBiTree(BiTree T){char ch;scanf("%c",&ch);if(ch=='#')T=NULL;else{if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(OVERFLOW);T->data=ch;CreateBiTree(T->lchild);CreateBiTree(T->rchild);}return T;}以上程序中已将将T定义为指针,出现的问题是指针T在变化的过程中,其指向已经发生改变,运行到最后T指向空,而不是原来的根结点。
- 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:。