二叉树深度的递归算法

二叉树深度的递归算法
二叉树深度的递归算法

//二叉树深度的递归算法

int depth(BTree root)

{

int ldepth,rdepth;

if(!root)

return 0;

else

{

ldepth = depth(root->lchild);

rdepth = depth(root->rchild);

return ldepth>rdepth?ldepth+1;rdepth+1;

}

}

// 二叉树深度的非递归算法(在中根遍历算法的基础上修改的来)int depth2(BTree root)

{

int top = 0;

int depth = 0,temp = 0; //temp 保存当前单分支的最大值BTree p = root;

BTree nodePointer[MAX_TREE_DEGREE];

while(p || top > 0)

{

if(p)

{

nodePointer[top] = p;

++ top;

++ depth; //统计单分支的深度

p = p->lchild;

}

else

{

-- top;

p = nodePointer[top];

p = p->rchild;

if(p == NULL)

{ //单分支结束

if(depth > temp )

temp = depth;

-- depth;

}

}//else

}//while

return temp;

}

数据结构求二叉树深度和度为2的节点个数代码实现

/* 求二叉树的深度 求二叉树度为2的节点个数 附带详细注释 */ # include # include //二叉树的节点结构体 typedef struct Tnode { char data; struct Tnode * lchild; struct Tnode * rchild; }NODE, * PTNODE; typedef int Status; //定义一个全局变量,用于统计度为2的节点 int count = 0; # define OK 1 # define ERROR 0 //创建一个二叉树 Status CreatTree( PTNODE & ); //先序遍历二叉树 Status InOrderTraveler( PTNODE & ); //求出树的深度 Status DeepTree( PTNODE & ); //求出树中度为2的节点个数 Status TwoDegreeNode( PTNODE & ); /* 先序创建一颗二叉树 这段代码在前面已经写烂~~( ﹁﹁) ~~~ */ Status CreatTree( PTNODE & T ) { char data; scanf( "%c", &data ); if( ' ' == data ) {

T = NULL; //如果是#,说明是一颗空树 } else { //节点有值,则创建这个节点 T = ( PTNODE )malloc( sizeof( NODE ) ); if( NULL == T ) { printf( "节点动态空间分配失败\n" ); return ERROR; } T -> data = data; CreatTree( T -> lchild ); CreatTree( T -> rchild ); } return OK; } /* 先序遍历二叉树 同样的,这一段代码也同样是写烂了 写这段代码的作用是为了检查刚刚那个二叉树生成了没*/ Status InOrderTraveler( PTNODE &T ) { if( NULL != T ) { printf( "%c", T -> data ); InOrderTraveler( T -> lchild ); InOrderTraveler( T -> rchild ); } return OK; } /* 求出二叉树的深度,这个才是今天的猪脚 */ int DeepTree( PTNODE & T ) { //设置两个整型变量,用于接收左子树和右子树的深度int LDeep, RDeep; if( NULL == T )

求树和二叉树的深度题目及源程序代码

树和二叉树 以下问题要求统一在一个大程序里解决。 10、按先序遍历的扩展序列建立二叉树的存储结构 11、二叉树先序、中序、后序遍历的递归算法 12、二叉树中序遍历的非递归算法 13、二叉树层次遍历的非递归算法 14、求二叉树的深度(后序遍历) 15、建立树的存储结构 16、求树的深度 17、 源程序代码: // tree.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include "stdio.h" #include "stdlib.h" #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OK 1 #define ERROR 0 #define TRUE 1 #define FALSE 0 #define OVERFLOW -1 typedef char TElemType; // 元素数据类型 typedef int Status; /* 二叉链表储存结构*/ typedef struct BiTNode { TElemType data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; bool CreateBiTree(BiTree &T) { //先序序列建立二叉树 char ch; scanf("%c",&ch); if (ch=='*') T = NULL;

else { if (!(T = (BiTNode *)malloc(sizeof(BiTNode)))) return ERROR; T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } return OK; } Status PrintElement(TElemType e) { // 访问函数 printf("%c", e); return OK; } Status PreOrderTraverse(BiTree T, Status(*Visit)(TElemType)) { //先序遍历二叉树的递归算法 if (T) { if (Visit(T->data)) if (PreOrderTraverse(T->lchild, Visit)) if (PreOrderTraverse(T->rchild, Visit)) return OK; return ERROR; }else return OK; } Status InOrderTraverse(BiTree T, Status(*Visit)(TElemType)) { //中序遍历二叉树的递归算法 if (T) { if (InOrderTraverse(T->lchild, Visit)) if (Visit(T->data)) if (InOrderTraverse(T->rchild, Visit)) return OK; return ERROR; }else return OK;

二叉树遍历C语言(递归,非递归)六种算法

数据结构(双语) ——项目文档报告用两种方式实现表达式自动计算 专业: 班级: 指导教师: 姓名: 学号:

目录 一、设计思想 (01) 二、算法流程图 (02) 三、源代码 (04) 四、运行结果 (11) 五、遇到的问题及解决 (11) 六、心得体会 (12)

一、设计思想 二叉树的遍历分为三种方式,分别是先序遍历,中序遍历和后序遍历。先序遍历实现的顺序是:根左右,中序遍历实现的是:左根右,后续遍历实现的是:左右根。根据不同的算法分,又分为递归遍历和非递归遍历。 递归算法: 1.先序遍历:先序遍历就是首先判断根结点是否为空,为空则停止遍历,不为空则将左子作为新的根结点重新进行上述判断,左子遍历结束后,再将右子作为根结点判断,直至结束。到达每一个结点时,打印该结点数据,即得先序遍历结果。 2.中序遍历:中序遍历是首先判断该结点是否为空,为空则结束,不为空则将左子作为根结点再进行判断,打印左子,然后打印二叉树的根结点,最后再将右子作为参数进行判断,打印右子,直至结束。 3.后续遍历:指针到达一个结点时,判断该结点是否为空,为空则停止遍历,不为空则将左子作为新的结点参数进行判断,打印左子。左子判断完成后,将右子作为结点参数传入判断,打印右子。左右子判断完成后打印根结点。 非递归算法: 1.先序遍历:首先建立一个栈,当指针到达根结点时,打印根结点,判断根结点是否有左子和右子。有左子和右子的话就打印左子同时将右子入栈,将左子作为新的根结点进行判断,方法同上。若当前结点没有左子,则直接将右子打印,同时将右子作为新的根结点判断。若当前结点没有右子,则打印左子,同时将左子作为新的根结点判断。若当前结点既没有左子也没有右子,则当前结点为叶子结点,此时将从栈中出栈一个元素,作为当前的根结点,打印结点元素,同时将当前结点同样按上述方法判断,依次进行。直至当前结点的左右子都为空,且栈为空时,遍历结束。 2.中序遍历:首先建立一个栈,定义一个常量flag(flag为0或者1),用flag记录结点的左子是否去过,没有去过为0,去过为1,默认为0.首先将指针指向根结点,将根结点入栈,然后将指针指向左子,左子作为新的结点,将新结点入栈,然后再将指针指向当前结点的左子,直至左子为空,则指针返回,flag置1,出栈一个元素,作为当前结点,打印该结点,然后判断flag,flag为1则将指针指向当前结点右子,将右子作为新的结点,结点入栈,再次进行上面的判断,直至当前结点右子也为空,则再出栈一个元素作为当前结点,一直到结束,使得当前结点右子为空,且栈空,遍历结束。 3.后续遍历:首先建立两个栈,然后定义两个常量。第一个为status,取值为0,1,2.0代表左右子都没有去过,1代表去过左子,2,代表左右子都去过,默认为0。第二个常量为flag,取值为0或者1,0代表进左栈,1代表进右栈。初始时指针指向根结点,判断根结点是否有左子,有左子则,将根结点入左栈,status置0,flag置0,若没有左子则判断结点有没有右子,有右子就把结点入右栈,status置0,flag置1,若左右子都没有,则打印该结点,并将指针指向空,此时判断flag,若flag为0,则从左栈出栈一个元素作为当前结点,重新判断;若flag为1则从右栈出栈一个元素作为当前结点,重新判断左右子是否去过,若status 为1,则判断该结点有没有右子,若有右子,则将该结点入右栈,status置1,flag置1,若没有右子,则打印当前结点,并将指针置空,然后再次判断flag。若当前结点status为2,且栈为空,则遍历结束。若指针指向了左子,则将左子作为当前结点,判断其左右子情况,按上述方法处理,直至遍历结束。

二叉树的基本参数计算

/*二叉树的基本参数计算*/ #include #include #define MaxSize 20 typedef int ElemType; #define OK 1 typedef struct BiTNode { ElemType data; struct BiTNode *lchild, *rchild; }BiTNode,*BiTree; //建立二叉树(按先序序列生成二叉树,#表示空节点) void CreateBiTree(BiTree *T) { char ch; scanf("%c",&ch); getchar();/*回车键(每次输入一个字符后,需敲回车键)*/ if(ch=='#') { printf("不产生子树。\n"); *T=NULL; } else { if(!(*T=(BiTNode *)malloc(sizeof(BiTNode)))) { printf("分配空间失败"); return; }//生成一个新节点 (*T)->data = ch; printf("产生左右子树。\n"); CreateBiTree(&(*T)->lchild); CreateBiTree(&(*T)->rchild); } } //交换左右子树产生新的树t返回到主函数 BiTNode *swap(BiTree T) { BiTree t,t1,t2; if(T==NULL) t=NULL; else {

t=(BiTNode*)malloc(sizeof(BiTNode)); t->data=T->data; t1=swap(T->lchild); //交换左右子树 t2=swap(T->rchild); t->lchild=t2; t->rchild=t1; } return(t); } //求树的叶子结点数 int leafs(BiTree T) { int num1,num2; if(T==NULL) return 0; else if(T->lchild==NULL&&T->rchild==NULL) return 1; else { num1=leafs(T->lchild); num2=leafs(T->rchild); return (num1+num2); } } //求二叉树的深度 int Depth(BiTNode *T) { int dep1,dep2; if(T==NULL) return(0); else { dep1=Depth(T->lchild); dep2=Depth(T->rchild); if(dep1>dep2) return(dep1+1); else return(dep2+1); } } //按广义表形式输出二叉树 void Disptree(BiTNode *T)

用递归非递归两种方法遍历二叉树

数据结构(双语) ——项目文档报告 用递归、非递归两种方法遍历二叉树 专业:计算机科学与技术 班级: 指导教师: 姓名:

学号: 目录 一、设计思想 (03) 二、算法流程图 (04) 三、源代码 (06) 四、运行结果 (12) 五、遇到的问题及解决 (14) 六、心得体会 (15)

一、设计思想 1.递归: (1)主函数main()主程序要包括:定义的二叉树T、建树函数、先序遍历函数、中序遍历函数、后序遍历函数。 (2)建树函数定义一个输入的数是字符型的,当ch为空时,T就为空值,否则的话就分配空间给T,T就指向它的结点,然后左指针域指向左孩子,右指针指向右孩子,若还有,继续调用,依次循环下去,直到ch遇到空时,结束。最后要返回建立的二叉树T。 (3)先序遍历函数根据先序遍历规则,当T为非空时,先输出结点处的数据,指针指向左、右孩子,依次进行下去。 (4) 中序遍历函数根据中序遍历规则,当T为非空时,先左指针指向左孩子数据,然后输出结点处的数据,再右指针指向右孩子,依次进行下去。 (5)后序遍历函数根据后序遍历规则,当T为非空时,先右指针指向右孩子,然后左指针指向左孩子,最后输出结点处的数据,依次进行下去。 2.非递归: (1)跟递归遍历二叉树的前提一样,首先应该创建一个二叉树,同样使用先序递归的方式创建二叉树。 (2)然后是中序,先序,后序非递归遍历二叉树。 (3)中序非递归遍历二叉树的思想是:首先是根节点压栈,当根节点的左子树不是空的时候,左子树压栈。直到左子树为空的时候,不再压栈。将栈顶元素出栈,访问栈顶元素,并将栈顶的右子树进栈。当右子树的左子树不是空的时候,左子树一直进栈,直到左子树为空,则不再进栈。重复上面的操作,直到栈空的时候。 (4)先序非递归遍历二叉树的思想是:首先是根节点进栈,然后当栈不为空的时候,将栈顶元素出栈,然后访问。同时将出栈元素的右子树进栈,左子树进栈。重复上面的操作,直到栈为空。 (5)后序非递归遍历二叉树的思想:首先是根节点进栈,当根节点的左子树不为空的时候,左子树进栈,直到左为空的时候,左子树不再进栈。指针指向的是右子树,当右子树为空的时候,直接访问根节点。当右子树不为空的时候,则右子树的指针进栈,当右子树的左子树不为空的时候,则左也进栈,直到左为空。重复上面的操作,直到栈为空的时候,则遍历树完成。

用递归和非递归算法实现二叉树的三种遍历

○A ○C ○D ○B ○E○F G 《数据结构与算法》实验报告三 ——二叉树的操作与应用 一.实验目的 熟悉二叉链表存储结构的特征,掌握二叉树遍历操作及其应用 二. 实验要求(题目) 说明:以下题目中(一)为全体必做,(二)(三)任选其一完成 (一)从键盘输入二叉树的扩展先序遍历序列,建立二叉树的二叉链表存储结构;(二)分别用递归和非递归算法实现二叉树的三种遍历; (三)模拟WindowsXP资源管理器中的目录管理方式,模拟实际创建目录结构,并以二叉链表形式存储,按照凹入表形式打印目录结构(以扩展先序遍历序列输入建立二叉链表结构),如下图所示: (基本要求:限定目录名为单字符;扩展:允许目录名是多字符组合) 三. 分工说明 一起编写、探讨流程图,根据流程图分工编写算法,共同讨论修改,最后上机调试修改。 四. 概要设计 实现算法,需要链表的抽象数据类型: ADT Binarytree { 数据对象:D是具有相同特性的数据元素的集合 数据关系R: 若D为空集,则R为空集,称binarytree为空二叉树;

若D不为空集,则R为{H},H是如下二元关系; (1)在D中存在唯一的称为根的数据元素root,它在关系H下无前驱; (2)若D-{root}不为空,则存在D-{root}={D1,Dr},且D1∩Dr为空集; (3)若D1不为空,则D1中存在唯一的元素x1,∈H,且存在D1上的关系H1是H的子集;若Dr不为空集,则Dr中存在唯一的元素 Xr,∈H,且存在Dr上的关系Hr为H的子集;H={,,H1,Hr}; (4) (D1,{H1})是一颗符合本定义的二叉树,称为根的左子树,(Dr,{Hr}) 是一颗符合本定义的二叉树,称为根的右子树。 基本操作: Creatbitree(&S,definition) 初始条件:definition给出二叉树S的定义 操作结果:按definition构造二叉树S counter(T) 初始条件:二叉树T已经存在 操作结果:返回二叉树的总的结点数 onecount(T) 初始条件:二叉树T已经存在 操作结果:返回二叉树单分支的节点数 Clearbintree(S) 初始条件:二叉树S已经存在 操作结果:将二叉树S清为空树 Bitreeempty(S) 初始条件:二叉树S已经存在 操作结果:若S为空二叉树,则返回TRUE,否则返回FALSE Bitreedepth(S,&e) 初始条件:二叉树S已经存在 操作结果:返回S的深度 Parent(S) 初始条件:二叉树S已经存在,e是S中的某个结点 操作结果:若e是T的非根结点,则返回它的双亲,否则返回空Preordertraverse(S) 初始条件:二叉树S已经存在,Visit是对结点操作的应用函数。 操作结果:先序遍历S,对每个结点调用函数visit一次且仅一次。 一旦visit失败,则操作失败。 Inordertraverse (S,&e) 初始条件:二叉树S已经存在,Visit是对结点操作的应用函数。

二叉树习题及答案

1.设一棵完全二叉树共有699 个结点,则在该二叉树中的叶子结点数? 1根据二叉树的第i层至多有2A(i - 1)个结点;深度为k的二叉树至多有2A k - 1 个结点(根结点的深度为1)”这个性质: 因为2A9-1 < 699 < 2A10-1 , 所以这个完全二叉树的深度是10,前9 层是一个满二叉树, 这样的话,前九层的结点就有2A9-1=511 个;而第九层的结点数是2A(9-1)=256 所以第十层的叶子结点数是699-511=188 个;现在来算第九层的叶子结点个数。由于第十层的叶子结点是从第九层延伸的,所以应该去掉第九层中还有子树的结点。因为第十层有188 个,所以应该去掉第九层中的188/2=94 个;所以,第九层的叶子结点个数是256-94=162,加上第十层有188 个,最后结果是350 个 2完全二叉树:若二叉树中最多只有最下面两层的结点的度可以小于2,并且最下面一层的结点 (叶结点) 都依次排列在该层最左边的位置上,这样的二叉树为完全二叉树。 比如图:完全二叉树除叶结点层外的所有结点数(叶结点层以上所有结点数)为奇数,此题中,699 是奇数,叶结点层以上的所有结点数为保证是奇数,则叶结点数必是偶数,这样我们可以立即选出答案为B!如果完全二叉树的叶结点都排满了,则是满二叉树,易得满二叉树的叶结点数是其以上所有层结点数+1 比如图: 此题的其实是一棵满二叉树,我们根据以上性质,699+1=700,700/2=350,即叶结点数为350,叶结点层以上所有结点数为350-1=349。 3完全二叉树中,只存在度为2 的结点和度为0 的结点,而二叉树的性质中有一条是: nO=n2+1 ; nO指度为0的结点,即叶子结点,n2指度为2的结点,所以2n2+1=699 n2=349 ; n0=350 2.在一棵二叉树上第 5 层的结点数最多是多少一棵二叉树,如果每个结点都是是满的,那么会满足2A(k-1)1 。所以第5 层至多有2A(5-1)=16 个结点! 3.在深度为5 的满二叉树中,叶子结点的个数为答案是16 ~ 叶子结点就是没有后件的结点~ 说白了~ 就是二叉树的最后一层~ 深度为K 的二叉树~ 最多有2Ak-1 个结点~ 最多有2A(k-1) 个结点~ 所以此题~ 最多有2A5-1=31 个结点~ 最多有2A(5-1)=16 个叶子结点~ 4.某二叉树中度为2 的结点有18 个,则该二叉树中有几个叶子结点?结点的度是指树中每个结点具有的子树个数或者说是后继结点数。 题中的度为2 是说具有的2 个子树的结点;二叉树有个性质:二叉树上叶子结点数等于度为2 的结点数加1。 5.在深度为7 的满二叉树中,度为2 的结点个数为多少,就是第一层只有一个节点,他有两个子节点,第二层有两个节点,他们也都有两个子节点以此类推,所以到第6 层,就有2的5次方个节点,他们都有两个子节点最后第7 层都没有子节点了。因为是深度为7 的。 所以就是1+2+4+8+16+32 了 2深度为1的时候有0个 深度为2的时候有1个 深度为3的时候有3个 深度为4的时候有7个 深度为n的时候有(2的n-1次方减1 )个 6?—棵二叉树中共有70个叶子结点与80个度为1的结点,则该二叉树中的总结点数为?

用递归,非递归两种方法遍历二叉树

一、设计思想 递归实现二叉树遍历的思想: 1.要遍历二叉树首先的问题是创建二叉树。二叉树的创建可以采用很多的方法。例如:先序,中序,后序,还可以采用层次的方法创建二叉树。本程序采用的是先序递归的方式创建的二叉树。 2.然后是中序,先序,后序递归遍历二叉树。递归的思想是一直调用方法本身。 3.中序递归遍历二叉树的思想是先访问左子树,然后访问根节点,最后访问右子树。当访问左子树或是右子树的时候,实际上调用的是函数本身。在这里就体现了递归的思想,当函数的返回值是0的时候,则返回上一次的程序,继续执行下面的语句。 4.先序递归遍历二叉树的思想是先访问根节点,然后访问左子树,最后访问右子树。同样如步骤3的方式相同,当访问左子树或者是右子树的收,实际上调用的是函数本身,直到返回值是0的时候,返回上一层的程序继续执行。 5.后序递归遍历二叉树的思想是先访问左子树,然后访问右子树,最后访问根节点。 同样跟步骤3的方式相同,当访问左子树或者右子树的时候实际上是调用的是方法本直到有返回值的时候才返回上一层的程序,继续执行. 非递归实现二叉树遍历的思想: 1.跟递归遍历二叉树的前提一样,首先应该创建一个二叉树,同样使用先序递归的方式创建二叉树。 2.然后是中序,先序,后序非递归遍历二叉树。 3.中序非递归遍历二叉树的思想是:首先是根节点压栈,当根节点的左子树不是空的时候,左子树压栈。直到左子树为空的时候,不再压栈。将栈顶元素出栈,访问栈顶元素,并将栈顶的右子树进栈。当右子树的左子树不是空的时候,左子树一直进栈,直到左子树为空,则不再进栈。重复上面的操作,直到栈空的时候。 4.先序非递归遍历二叉树的思想是:首先是根节点进栈,然后当栈不为空的时候,将栈顶元素出栈,然后访问。同时将出栈元素的右子树进栈,左子树进栈。重复上面的操作,直到栈为空。 5.后序非递归遍历二叉树的思想:首先是根节点进栈,当根节点的左子树不为空的时候,左子树进栈,直到左为空的时候,左子树不再进栈。指针指向的是右子树,当右子树为空的时候,直接访问根节点。当右子树不为空的时候,则右子树的指针进栈,当右子树的左子树不为空的时候,则左也进栈,直到左为空。重复上面的操作,直到栈为空的时候,则遍历树完成。 二、算法流程图 递归方法遍历二叉树的流程图如图1

求二叉树中节点的最大距离

求二叉树中节点的最大距离
如果我们把二叉树看成一个图,父子节点之间的连线看成是双向的,我们姑且定义“距 离”为两个节点之间边的个数。 写一个程序求一棵二叉树中相距最远的两个节点之间的距离。 如图 3-11 所示,粗箭头的边表示最长距离:
图 3-11
树中相距最远的两个节点 A,B

分析与解法
我们先画几个不同形状的二叉树,(如图 3-12 所示),看看能否得到一些启示。
图 3-12
几个例子?
从例子中可以看出,相距最远的两个节点,一定是两个叶子节点,或者是一个叶子节点 到它的根节点。(为什么?) 【解法一】 根据相距最远的两个节点一定是叶子节点这个规律,我们可以进一步讨论。 对于任意一个节点,以该节点为根,假设这个根有 K 个孩子节点,那么相距最远的两 个节点 U 和 V 之间的路径与这个根节点的关系有两种情况: 1. 若路径经过根Root,则U和V是属于不同子树的,且它们都是该子树中到根节点最远 的节点,否则跟它们的距离最远相矛盾。这种情况如图3-13所示:
图 3-13
相距最远的节点在左右最长的子树中

2. 如果路径不经过Root,那么它们一定属于根的K个子树之一。并且它们也是该子树中 相距最远的两个顶点。如图3-14中的节点A:
图 3-14
相距最远的节点在某个子树下
因此,问题就可以转化为在子树上的解,从而能够利用动态规划来解决。 设第 K 棵子树中相距最远的两个节点:Uk 和 Vk,其距离定义为 d(Uk, Vk),那么节点 Uk 或 Vk 即为子树 K 到根节点 Rk 距离最长的节点。不失一般性,我们设 Uk 为子树 K 中到根 节点 Rk 距离最长的节点,其到根节点的距离定义为 d(Uk, R)。取 d(Ui, R)(1≤i≤k)中 最大的两个值 max1 和 max2,那么经过根节点 R 的最长路径为 max1+max2+2,所以树 R 中 相距最远的两个点的距离为:max{d(U1, V1), …, d(Uk, Vk),max1+max2+2}。 采用深度优先搜索如图 3-15,只需要遍历所有的节点一次,时间复杂度为 O(|E|)= O (|V|-1),其中 V 为点的集合,E 为边的集合。
图 3-15
深度遍历示意图?
示例代码如下,我们使用二叉树来实现该算法。 代码清单 3-11
// 数据结构定义

二叉树中序遍历的非递归算法实现

试验五 课程名称实验室名称 实验名称二叉树中序遍历的非递归算法实现 指导教师成绩 1、实验目的 二叉树中序遍历的非递归算法实现 2、实验原理和内容 二叉树中序遍历的非递归算法实现 3、实验步骤 1.链式存储结构的定义和栈结构的定义 2.编写进栈函数push和出栈函数pop实现中序遍历过程中需存储的数的进栈和出栈过程 3.创建一棵二叉树 4.对该二叉树进行中序遍历,采用非递归算法实现

4、程序及运行结果(或实验数据记录及分析)#include #include typedef char datatype; //* 链式存储结构*// typedef struct node{ datatype data; struct node *lchild,*rchild; }bintnode; typedef bintnode *bintree; typedef struct stack{ /* 栈结构定义*/ bintree data[100]; int top; }seqstack; void push(seqstack *s,bintree t) { s->data[s->top]=t; s->top++; } bintree pop(seqstack *s) { if (s->top!=0) { s->top--; return(s->data[s->top]); } else return NULL; } void createbintree(bintree *t) { char ch; if ((ch=getchar())==' ') *t=NULL; else { *t=(bintnode *)malloc(sizeof(bintnode)); (*t)->data=ch; createbintree(&(*t)->lchild); createbintree(&(*t)->rchild); } } void inorder1(bintree t) {

数据结构中二叉树各种题型详解及程序

树是一种比较重要的数据结构,尤其是二叉树。二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒。二叉树是递归定义的,因此,与二叉树有关的题目基本都可以用递归思想解决,当然有些题目非递归解法也应该掌握,如非递归遍历节点等等。本文努力对二叉树相关题目做一个较全的整理总结,希望对找工作的同学有所帮助。 二叉树节点定义如下: structBinaryTreeNode { intm_nValue; BinaryTreeNode* m_pLeft; BinaryTreeNode* m_pRight; }; 相关链接: 轻松搞定面试中的链表题目 题目列表: 1. 求二叉树中的节点个数 2. 求二叉树的深度 3. 前序遍历,中序遍历,后序遍历 4.分层遍历二叉树(按层次从上往下,从左往右) 5. 将二叉查找树变为有序的双向链表 6. 求二叉树第K层的节点个数 7. 求二叉树中叶子节点的个数 8. 判断两棵二叉树是否结构相同 9. 判断二叉树是不是平衡二叉树 10. 求二叉树的镜像 11. 求二叉树中两个节点的最低公共祖先节点 12. 求二叉树中节点的最大距离 13. 由前序遍历序列和中序遍历序列重建二叉树 14.判断二叉树是不是完全二叉树 详细解答 1. 求二叉树中的节点个数 递归解法: (1)如果二叉树为空,节点个数为0 (2)如果二叉树不为空,二叉树节点个数= 左子树节点个数+ 右子树节点个数+ 1 参考代码如下: 1.int GetNodeNum(BinaryTreeNode * pRoot) 2.{ 3.if(pRoot == NULL) // 递归出口 4.return 0; 5.return GetNodeNum(pRoot->m_pLeft) + GetNodeNum(pRoot->m_pRight) + 1; 6.}

求二叉树的深度叶子结点数总结点数()

#include"malloc.h" #define NULL 0 #include"stdio.h" typedef struct node { char data; struct node *lchild,*rchild; }NODE; int count; NODE *crt_bt_pre()/*二叉树先序创建算法*/ { NODE * bt; char ch; printf("\n\t\t\t"); scanf("%c",&ch); getchar(); if(ch==' ') bt=NULL; else { bt=(NODE*)malloc(sizeof(NODE)); bt->data=ch; printf("\n\t\t\t请输入%c结点的左孩子:",bt->data); bt->lchild=crt_bt_pre(); printf("\n\t\t\t请输入%c结点的右孩子:",bt->data); bt->rchild=crt_bt_pre(); } return(bt); } void Preorder(NODE* bt)/*二叉树先序递归遍历算法*/ { if(bt!=NULL) { printf("\n\t\t\t %c",bt->data); Preorder(bt->lchild); Preorder(bt->rchild); } } void Inorder(NODE* bt) {

if(bt!=NULL) { Inorder(bt->lchild); printf("\n\t\t\t %c",bt->data); Inorder(bt->rchild); } } void Postorder(NODE* bt) { if(bt!=NULL) { Postorder(bt->lchild); Postorder(bt->rchild); printf("\n\t\t\t %c",bt->data); } } int CountLeaf(NODE *bt)/*求二叉树叶子结点数的递归遍历算法*/ { if(bt==NULL) return 0; if(bt->lchild==NULL&&bt->rchild==NULL) count++; CountLeaf(bt->lchild); CountLeaf(bt->rchild); return(count); } int CountNode (NODE* bt)/*求二叉树结点数的递归遍历算法*/ { if(bt==NULL) return 0; else count++; CountNode(bt->lchild); CountNode(bt->rchild); return(count); } int TreeDepth(NODE* bt)/*求二叉树深度的递归遍历算法*/ { int x,y; if(bt==NULL)

二叉树习题及答案(考试学习)

1.设一棵完全二叉树共有699个结点,则在该二叉树中的叶子结点数? 1根据“二叉树的第i层至多有2^(i ? 1)个结点;深度为k的二叉树至多有2^k ? 1个结点(根结点的深度为1)”这个性质: 因为2^9-1 < 699 < 2^10-1 ,所以这个完全二叉树的深度是10,前9层是一个满二叉树, 这样的话,前九层的结点就有2^9-1=511个;而第九层的结点数是2^(9-1)=256 所以第十层的叶子结点数是699-511=188个; 现在来算第九层的叶子结点个数。 由于第十层的叶子结点是从第九层延伸的,所以应该去掉第九层中还有子树的结点。因为第十层有188个,所以应该去掉第九层中的188/2=94个; 所以,第九层的叶子结点个数是256-94=162,加上第十层有188个,最后结果是350个 2完全二叉树:若二叉树中最多只有最下面两层的结点的度可以小于2,并且最下面一层的结点(叶结点)都依次排列在该层最左边的位置上,这样的二叉树为完全二叉树。 比如图: 完全二叉树除叶结点层外的所有结点数(叶结点层以上所有结点数)为奇数,此题中,699是奇数,叶结点层以上的所有结点数为保证是奇数,则叶结点数必是偶数,这样我们可以立即选出答案为B! 如果完全二叉树的叶结点都排满了,则是满二叉树,易得满二叉树的叶结点数是其以上所有层结点数+1比如图: 此题的其实是一棵满二叉树,我们根据以上性质,699+1=700,700/2=350,即叶结点数为350,叶结点层以上所有结点数为350-1=349。 3完全二叉树中,只存在度为2的结点和度为0的结点,而二叉树的性质中有一条是:n0=n2+1;n0指度为0的结点,即叶子结点,n2指度为2的结点,所以2n2+1=699 n2=349;n0=350 2.在一棵二叉树上第5层的结点数最多是多少 一棵二叉树,如果每个结点都是是满的,那么会满足2^(k-1)1。 所以第5层至多有2^(5-1)=16个结点! 3.在深度为5的满二叉树中,叶子结点的个数为 答案是16 ~ 叶子结点就是没有后件的结点~ 说白了~ 就是二叉树的最后一层~ 深度为K的二叉树~ 最多有2^k-1个结点~ 最多有2^(k-1)个结点~ 所以此题~ 最多有2^5-1=31个结点~ 最多有2^(5-1)=16个叶子结点~ 4.某二叉树中度为2的结点有18个,则该二叉树中有几个叶子结点? 结点的度是指树中每个结点具有的子树个数或者说是后继结点数。 题中的度为2是说具有的2个子树的结点; 二叉树有个性质:二叉树上叶子结点数等于度为2的结点数加1。 5.在深度为7的满二叉树中,度为2的结点个数为多少, 就是第一层只有一个节点,他有两个子节点,第二层有两个节点,他们也都有两个子节点以此类推,所以到第6层,就有2的5次方个节点,他们都有两个子节点

数据结构 求二叉树的深度

第五次上机实验报告 计科093xx川5310 实验内容: 求二叉树的xx 程序清单: #include #include #define OK 1 #define OVERFLOW -2 typedef int status; typedef struct BiNode//二叉链表{char Data; struct BiNode* lChild; struct BiNode* rChild; }BiNode,*pBiNode; typedef struct SNode/*链栈的结点类型*/{pBiNode elem; /*栈中的元素是指向二叉链表结点的指针*/ struct SNode *next; }SNode; structlink//队列链表{structBiNode *p; structlink*next; };

status CreateTree(BiNode** pTree); intTreeHeight (BiNode* pTree);//二叉树的高度 status Visit(char Data); voidDisplay(BiNode* pTree,int Level); BiNode *pRoot=NULL; status CreateTree(BiNode** pTree) /*Input Example: abd##e##cf##g##*/{char ch; scanf("%c",&ch); if(ch=='#'){(*pTree)=NULL;}else{if(!((*pTree)=(BiNode*)malloc(sizeof(BiNode)))){ exit(OVERFLOW);}(*pTree)->Data=ch; CreateTree(&((*pTree)->lChild)); CreateTree(&((*pTree)->rChild));}return OK;}int TreeHeight(BiNode* pTree)//二叉树的高度{int hl ,hr ; //左右子树的高度 if (pTree == NULL) return 0 ; else hl = TreeHeight(pTree-> lChild); hr = TreeHeight (pTree-> rChild); if (hl>hr) return (hl +1); else return (hr +1);}status Visit(char Data){printf("%c",Data);

二叉树中以广义表,(先序,中序后序)递归,中序非递归输出

#include #include #define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 #define OVERFLOW -2 #define OK 1 #define ERROR -1 #define TRUE 1 #define FALSE 0 typedef char TElemType; typedef int Status; typedef struct BiTNode{ // 二叉链表储存结构 TElemType data; struct BiTNode *lchild,*rchild; }BiTNode,*BiTree; Status CreateBiTree(BiTree &T){//先序序列建立二叉树 char ch; scanf("%c",&ch); if(ch=='#') T=NULL; else{ if(!(T=(BiTNode*)malloc(sizeof(BiTNode)))) return(OVERFLOW); T->data=ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } return OK; } void PrintBiTree(BiTree &T){ //以广义表的形式输出 if(T!= NULL) { printf("%c", T->data); if(T->lchild != NULL || T->rchild!=NULL) { printf("("); PrintBiTree(T->lchild); if(T->rchild != NULL) { printf(",");

二叉树的性质总结

一、二叉树的性质 性质1、二叉树的第i 层上至多有2 i-1(i ≥1)个结点。用数学归纳法证明 推广:k 叉树(或度为k 的树)的第i 层上至多有k i-1(i ≥1)个结点 性质2、度为h 的二叉树中至多含有2h-1个结点。 21-1 + 2 2-1+……+ 2 h-1 = 2 h -1 推广:深度为h 的k 叉树(或度为k 的树)中至多含有 (k h -1)/(k-1)个结点 k 1-1 + k 2-1+……+ k h-1 =( k h -1)/(k-1) 性质3、若在任意一棵二叉树中,有n0个叶子结点, 有n2个度为2的结点,则:n0=n2+1 证明:设:有n0个叶子结点,有n1个度为1的结点,有n2个度为2的结点, 则二叉树中结点总数为:n=n0+n1+ n2 (1) 设分支的总数为m,则:m= n1+2 n2 (2) 因为n=m+1(3) 所以: n0+n1+ n2 = n1+2 n2 +1 整理得: n0= n2+1 推广: 度为k 的树有n 1个度为1的结点, n 2个度为2的结点,n k 个度为k 的结点则n 0为: 性质3推广的证明于性质3的证明 设:有n 0个叶子结点,有n 1个度为1的结点, n 2个度为2的结点,n k 个度为k 的结点 则结点总数为:n=n 0+n 1+ n 2 +……+n k (1) 设分支的总数为m,则:m= n 1+2 n 2+……+kn k 因为n=m+1(3) 所以:n 0+n 1+ n 2 +……+n k = n 1+2 n 2+……+kn k +1 整理得: n 0= 0n 1+1n 2+……+(k-1)n k +1 性质4、具有n 个结点的完全二叉树,其深度为?㏒2n ?+1 证明:设n 个结点的完全二叉树的深度为k ,根据性质2可知,k-1层满二叉树的结点总数为: 2k-1-1 k 层满二叉树的结点总数为: 2k -1 显然有: 2k-1 - 1 < n ≤ 2k - 1 [ 2k- 1 ≤ n < 2k 取对数有:k -1 ≤ log 2n < k 因为k 是整数,所以k -1 = ?log 2n ? , k= ?㏒2n ?+1 结论成立。 推广: 具有n 个结点的完全k 叉树,其深度为? log k (k-1) n ? +1 设n 个结点的完全k 叉树的深度为h ,根据性质2推广可知, h-1层满k 叉树的结点总数为:(k h-1-1)/(k-1) h 层满二叉树的结点总数为:(k h -1)/(k-1) 显然有: (k h-1-1)/(k-1) < n ≤ (k h -1)/(k-1) k h-1-1 <(k-1) n ≤ k h -1 k h-1 ≤ (k-1) n< k h 取对数有:h -1 ≤ log k (k-1) n 1,则该结点的双亲结点编号为 [k/2 ] 。 (2)若2k<=n,则编号为k 的左孩子结点编号为2k;否则该结点无左孩子结点(显然也没有右孩子结点)。 ∑ k i=1 ( i- 1)n i +1

相关文档
最新文档