考研王道算法题——盘点二叉树的相关算法题目

2~6题为二叉树的宽度、高度题目 

1、已知一棵二叉树按顺序存储结构进行存储,设计一个算法,求编号为i和j的两个节点的最近的公共祖先结点的值。

#include <stdio.h>

/*
*	二叉树按顺序存储 
*	我们应该明白一点。二叉树的顺序存储是按照完全二叉树进行存储的!!
*	对完全二叉树按从上到下,从左到右的顺序依次编码1,2...n:它是有以下关系的: 
*	当i>1时,结点的双亲编号为i/2(向下取整),即当i为偶数时,其双亲的编号为i/2,它是双亲的左孩子;它是奇数时,其双亲的编号为(i-1)/2,它是双亲的右孩子
*	当2i<=n时,结点i的左孩子编号为2i,否则无左孩子;
*	当2i+1<=n时,结点i的右孩子编号为2i+1,否则无右孩子;
*	结点i所在的层次(深度)为log2i+1 
*
*   解题思路:
*	(1)若i>j,则结点i所在层次大于等于结点j,那么若结点i的双亲结点=j,那么便是其最近公共祖先结点,否则令i=i/2,即以结点i的双亲结点为起点,继续查找
*	(2) 若j>i,则结点i所在层次大于等于结点j,那么若结点j的双亲结点=i,那么便是其最近公共祖先结点,否则令j=i/2,即以结点j的双亲结点为起点,继续查找 
*/

int common_ancestor(int* T,int i,int j){
	if(i==j)
		return i;
	else if(i>j)
		common_ancestor(T,i/2,j);//这里除以2就是它的双亲节点(上面提到的完全二叉树顺序存储关系)
	else
		common_ancestor(T,i,j/2);	
} 


int main(){
	int T[]={0,1,2,3,0,4,0,5,0,0,6,0};
	printf("%d",common_ancestor(T,2,10));
} 

非递归解法:

int common_ancestor2(int* T,int i,int j){
	if(T[i]!='#'&&T[j]!='#'){
		while(i!=j){
			if(i>j)
				i=i/2;
			else
				j=j/2;
		}
	}
} 

2、试给出二叉树的自下而上,从右向左的层次遍历算法。

层次遍历

#include <stdio.h>

/*
*	我们首先想到的层次序列都是自上而下,从左到右。欸,刚好相反,那么相反我们想到的是什么?没错,就是栈
*	首先就是利用原有的层次遍历算法,然后再出队的同时把各结点压入栈中。在所有结点都入栈之后,我们再从栈顶开始依次访问。
*	具体实现步骤:
*	(1)首先把根结点入队列
*	(2)把一个元素出队,接着把该结点入栈
*	(3)如果该结点的左孩子不为空,那么把左孩子入队列; 如果该结点的右孩子不为空,那么把右孩子入队列;
*	(4)若队列不为空。跳转到(2)继续执行
*	(5)队列为空,跳出循环。对栈进行一次遍历。 
*/

void InverLevel(BiTree bt){
	Stack s,Queue Q;//创建栈和队列 
	BitNode* p;
	if(bt!=NULL){
		InitStack(s);//初始化栈 
		InitQueue(Q);//初始化队列 
		EnQueue(Q,bt);//根节点入队
		while(!QueueEmpty(Q)){
			DeQueue(Q,p);//出队列 
			Push(s,p);//并且入栈
			if(p->lchild)
				EnQueue(Q,p->lchild);//如果该结点的左孩子不为空,那么把左孩子入队列
			if(p->rchild)
				EnQueue(Q,p->rchild);//如果该结点的右孩子不为空,那么把右孩子入队列;
		}
		//跳出循环后,对栈进行一次遍历
		while(!StackEmpty(s)){
			Pop(s,p);
			visit(p->data);
		}
	}
} 

  3、假设二叉树采用二叉链表存储结构,设计一个算法求二叉树的高度

(1)非递归版

层次遍历

#include <stdio.h>


/*
*	非递归求二叉树高度
	首先我们先设置一个变量level,来记录当前结点的层数(深度)。
	然后设置一个变量last,来指向当前层次的最右结点。last初始化为根结点的序号,即1
	步骤:
	(1)每次层次遍历出队时,把出队的结点的左右孩子入队
	(2)接着把出队的结点和last指针比较,若两者相同则层次level+1。
	(3)并让last指针指向下一层最右结点。
	(也就是当前队列的队尾,这个地方可以自己画图好好理解一下。
	给个思路:出队的结点若是最右结点,那么他的左右孩子便是下一层的最右结点(右孩子不存在,那么便是其左孩子是下一层最右结点))		 
*/ 

#define MaxSize 100
int Btdepth(BiTree T){
	
	if(T==NULL)
		return 0;
		
	int last=0;//当前层次的最右结点
	int level=0;//记录当前结点的层次
	BiTree Q[MaxSize];//设置队列Q,元素是二叉树结点指针且容量足够
	int front=rear=-1;//队列初始化
	BiTree p; 
	Q[++rear]=T;//根结点入队列 
	while(front<rear){	//队列不为空,则循环 
		p=Q[++front];//出队
		if(p->lchild)
			Q[++rear]=p->lchild;
		if(p->rchild)
			Q[++rear]=p->rchild;
		if(front==last){ //出队的元素和last指针相同,层次+ 1
			level++;
			last=rear; //last指向下一层最右结点 
		}
	}	 
	return level;	
}

(2)递归版

#include <stdio.h>

/*
*	递归嘛,考虑两个条件:递归体和递归出口
	步骤:
        (1)如果树为空,那么返回0;
		(2)如果树不为空,
            递归该结点的左子树    --- 递归体
            递归该结点的右子树    --- 递归体
            返回子树最大高度+1(加1是因为还有根结点) ---  递归出口
*/

int BtDepth(BiTree T){
	if(T==NULL)
		return 0;
	int ldep=BtDepth(T->lchild);
	int rdep=BtDepth(T->rchild);
	if(ldep>rdep)
		return ldep+1;
	else
		return rdep+1;
}

4、以孩子兄弟链表为存储结构,请设计递归算法求树的深度。

#include<stdio.h>

/*
	思想:
		说说孩子兄弟表示法,一个结点包含结点值,指向结点第一个孩子结点的指针,指向结点下一个兄弟结点的指针
		那么,我们想从这个孩子兄弟链表表示的二叉树中求原来的树的高度,我们画个图就能理清楚了。
			根结点的左结点是其孩子结点,那么它的高度加上根结点(即1)就是整棵树的高度(暂定)。
			而根结点的右结点是其兄弟结点,也就是在原来的树中,它的高度和根结点是一样的!!
			所以,孩子兄弟链表表示的二叉树中,高度就是max(第一子女高度+1,兄弟子树高度)
	步骤:
		(1)如果树为空,返回0
		(2)其他情况(包括树的两个结点指针都为空),
			递归求第一子女高度
			递归求兄弟树高度 
			返回第一子女高度+1和兄弟子树高度的大者 
*/ 

int Height(CSTree bt){
	if(bt==NULL)
		return 0;
	else{
		int hc=Height(bt->firstchild);
		int hs=Height(bt->nextsibling);
		if(hc+1>hs)
			return hc+1;
		else
			return hs;
	}
}

5、设计一个算法,求出指定结点在给定二叉排序树中的层次

#include <stdio.h>

/*
	思想:
		这道题其实考的就是二叉排序树的查找。那么我们应该明确一点,
		(1)在二叉排序树中,二叉排序树的查找是从根结点开始,查找一次就下降一层!!
		(2)因此,查找该结点所用的次数就是该结点在二叉排序树中的层次。
		(3)采用二叉排序树非递归查找算法,用n保存层次,每查找1次,n就加1,直到找到相应的结点
		
	步骤:
        设二叉树采用二叉链表存储结构
		(1)定义一个统计查找次数的变量n
		(2)如果树不为空,那么n++; 
		(3)开始进入循环,若结点的值和当前结点不一样,
				如果小于当前结点关键字,那么在其左子树上查找 
				如果大于当前结点关键字,那么在其右子树上查找
				并且n++; 
*/ 

int level(BiTree bt,BSTNode *p){
	
	int n=0;//统计查找次数的变量n
	BiTree t=bt;
	if(bt!=NULL){
		n++;
		while(t->data!=p->data){
			if(p->data<t->data)
				t=t->lchild;
			else
				t=t->rchild;	
			n++;
		}
	}
	return n;	
}

 6、假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树b的宽度(即具有结点个数最多的那一层的结点个数)

#include <stdio.h>

/*
	思想:
		还是用到层次遍历。但这一次,我们的队列不仅存放结点的值,还存放结点对应的层次!! 
		把所有结点都存放完后,再通过扫描队列求出各层的结点总数,最大的即为二叉树的宽度。
	
	步骤:
		(1)初始化队列,把根结点入队,并把其层次置为1
		(2)还是照常的出队,但这里还需要出队结点的层次!!
		(3)然后就是把该结点的左右孩子入队,且左右孩子的层次为当前层次k+1;
		(4)全部入队列后就开始扫描队列,将k重置为1表示从第一层开始查找。
		(5)用n统计每一层的结点个数,每一层都和最大值max比较一次,保存最大的结点数。 每一层扫描后,k需要置为下一层的层次。 
*/

typedef struct{
	BiTree data[MaxSize]; //保存队列中的结点指针 
	int level[MaxSize]; //保存data中相同下标结点的层次 
	int front,rear;
}Qu; 

int BtWidth(BiTree T){
	BiTree p; //暂存出队的结点 
	int k; //暂存出队的层次
	Qu.front=Qu.rear=-1;
	Qu.rear++;
	Qu.data[Qu.rear]=T;//根结点入队 
	Qu.level[Qu.rear]=1;//根结点层次为1
	while(Qu.front<Qu.rear){
		Qu.front++;
		p=Qu.data[Qu.front]; //出队结点 
		k=Qu.level[Qu.front]; //出队结点的层次
		if(p->lchild){ //左孩子进队列 
			Qu.rear++;
			Qu.data[Qu.rear]=p->lchild;
			Qu.level[Qu.rear]=k+1;
		}
		if(p->rchild){ //右孩子进队列 
			Qu.rear++;
			Qu.data[Qu.rear]=p->rchild;
			Qu.level[Qu.rear]=k+1;
		} 
	}
	int i=0,k=1; //k重置为1表示从第一层开始查找,i扫描队中所有元素 
	int max=0;//保存同一层最多的结点个数 
	while(i<=Qu.rear){
		n=0; //n统计第k层的结点个数
		while(i<=Qu.rear&&Qu.level[i]==k){
			i++;
			n++;
		} 
		if(n>max)
			max=n;	
	}
	k=Qu.level[i];
	return max;
} 

7、设一棵二叉树中各结点的值互不相同,其先序序列和中序序列分别存于两个一维数组A[1...n],B[1...n]中,试编写算法建立该二叉树的二叉链表。

#include <stdio.h>

/*
*	思路: 
	首先我们需要根据先序序列确定根结点A,然后通过A在中序序列中划分出二叉树的左右子树。
	基本思路就是这样,仔细一想,是不是和快速排序很相似(先确定枢轴,然后通过枢轴划分。
	再划分好的区域继续划分,思路基本上是一样的,所以我们这个算法采用的也是递归算法)
	
	这个算法最后是自己动手画两个图,一个先序序列,一个后序序列,然后通过根结点去确定左子树和右子树的长度表达式
	
	步骤 :
	(1)根据先序序列确定树的根结点
	(2)通过根结点在中序序列中划分出二叉树的左右子树。然后根据左右子树结点在先序序列中的次序确定根结点,
	再继续跳回第(1)步,然后不断划分 
	如此重复上述步骤,直到每棵子树仅有一个结点为止。	 
*/

//A为先序序列,B为中序序列
BiTree PreInCreat(ElemType A[],ElemType B[],int l1,int r1,int l2,int r2){
	//l1,r1为先序序列的第一和最后一个结点下标
	//l2,r2为中序序列的第一和最后一个结点下标 
	BiTNode *root=(BiTNode *)malloc(sizeof(BiTNode));
	root->data=A[l1]; //通过先序序列确定的根结点 
	for(int i=l2,B[i]!=root->data;i++) //确定中序序列的根结点 
		;
	int lLen=i-l2; //左子树长度 
	int rLen=r2-i; //右子树长度 
	if(lLen)
		root->lchild=PreInCreat(A,B,l1+1,l1+lLen,l2,i-1); //最后的i-1写成l2+len-1也一样 
	else
		root->lchild=NULL;
	if(rLen)
		root->rchild=PreInCreat(A,B,r1-rLen+1,r1,r2-rLen+1,r2);
	else
		root->rchild=NULL;
	return root;
} 

9、假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一个给定二叉树的所有双分支结点。

递归

#include <stdio.h>

/*
	这道题相对来说还是比较简单的,就是先判断根结点是否是双分支结点,然后再判断其左右子树。直到所有子树都遍历完。
	步骤:
	递归出口:
		如果树为空,返回0
	递归体:
		如果该结点左右子树不为空,递归其左右子树并 + 1
		其他情况(该结点为叶子结点或单分支结点),递归其左右子树。 
*/ 

int DsonNodes(BiTree T){
	if(T==NULL)
		return 0;
	else if(T->lchild!=NULL&&T->rchild!=NULL)
		return DsonNodes(T->lchild) + DsonNodes(T->rchild) + 1; //是双分支结点,+1 
	else 
		return DsonNodes(T->lchild) + DsonNodes(T->rchild);
}

10、设树B是一棵采用链式结构存储的二叉树,编写一个把树B中所有结点的左、右子树进行交换的函数。

递归

#include <stdio.h>

/*
	步骤: 
	(1)先把结点b的左孩子的左右子树进行交换,
	(2)再对结点b的右孩子的左右子树进行交换 
	(3)最后交换结点b的左右孩子
	当结点为空时递归结束!!
	
	思想: 
	乍一看是不是很眼熟,没错,其实就是递归版的后序遍历!!再后序遍历的基础上增加了交换结点而已。 
*/

void swap(BiTree T){
	if(T){
		swap(T->lchild);//递归地交换左子树 
		swap(T->rchild);//递归地交换右子树 
		//下面就是交换左右孩子 
		BiTree temp=T->lchild;
		T->lchild=T->rchild;
		T->rchild=temp;
	} 
} 

11、假设二叉树采用二叉链表存储结构存储,设计一个算法,求先序遍历序列中第k(1<=k<=二叉树结点个数)个结点的值。

递归

#include <stdio.h>

/*
	思想:
		在先序遍历的基础上增加一个全局变量i,当i==k时返回结点即可
		
	步骤:
		(1)设置一个全局变量i记录已访问过的结点的序号,其初值根结点在先序序列的序号,即1
		(2)如果是空树,返回特殊字符'#'
		(3)当i==k时,表明找到目标结点,返回结点的值
		(4)若i!=k,i++,并递归地在该结点的左子树中查找,若找到则返回,否则递归地在右子树中查找 
*/ 

int i=1; //置一个全局变量i记录已访问过的结点的序号
ElemType PreNode(BiTree T,int k){
	
	if(T==NULL)
		return '#';
	if(i==k)
		return T->data;
	i++; //下一个结点 
	ElemType ch=PreNode(T->lchild,k); //递归地在该结点的左子树中查找
	if(ch!='#')
		return ch; //在左子树中,则返回该结点 
	ch=PreNode(T->rchild,k); //递归地在右子树中查找
	return ch;
}

12、设有一棵满二叉树(所有结点值均不同),已知其先序序列为pre,设计一个算法求其后序序列post。

#include <stdio.h>

/*
	思想: 
		对于一般二叉树,单纯通过先序序列是无法确定后序序列的。
		但是对于满二叉树来说,
			(1)其任意一个结点的左右子树的结点数相等。
			(2)同时,其先序序列的第一个结点为后序序列的最后一个结点!!
	
	步骤:
		递归体:
			(1)转换左子树,参数为先序序列的左子树,及其第一个结点,最后一个结点,后序序列的左子树,及其第一个结点,最后一个结点	 
			(2)转换右子树,参数为先序序列的右子树,及其第一个结点,最后一个结点,后序序列的右子树,及其第一个结点,最后一个结点 
*/

void PreToPost(ElemType pre[],int l1,int r1,ElemType post[],int l2,int r2){
	int half;
	if(l1<=r1){
		post[r2]=pre[l1];
		half=(r1-l1)/2;
		PreToPost(pre, l1+1, l1+half, post, l2, l2+half-1);//转换左子树
		PreToPost(pre, l1+half+1, r1, post, l1+half, r2-1);//转换右子树
	}
}

13、设计一个算法将二叉树的叶结点按从左到右的顺序连成一个单链表,表头指针为head。二叉树按二叉链表方式存储,链接时用叶结点的右指针域来存放单链表指针。

中序遍历

#include <stdio.h>

/*
	思想: 
		题目说是将二叉树的叶结点按从左到右的顺序连成一个单链表,
		那么就需要遍历单链表,通常我们所用的先序、中序、后序遍历对于叶结点的访问顺序都是从左到右,
		所以我们只需要任选一种遍历算法,再此基础上对于遍历到的结点进行判断,如果是叶结点那么将其链入链表即可。 
	
	步骤:
		(1)设置全局变量的头结点head和前驱结点pre(初始为空)。
		(2)进行递归地中序遍历。 
		(3)对于遍历到的叶结点,第一个叶结点(其pre=NULL)需要另外处理:第一个叶结点由指针head指向
			其余叶结点,则pre->rchild指向当前叶结点。
			对于最后一个结点,其rchild指针为空	
*/

LinkedList head,pre=NULL; //设置全局变量的头结点head和前驱结点pre(初始为空)。
LinkedList InOrder(BiTree bt){
	if(bt){
		InOrder(bt->lchild); //中序遍历左子树 
		if(bt->lchild==NULL&&bt->rchild==NULL){
			if(pre==NULL){ //处理第一个结点 
				head=bt;
				pre=bt;
			}else{
				pre->rchild=bt; //前驱结点指针pre的右指针指向当前结点 
				pre=bt;
			}
		} 
		InOrder(bt->rchild); //中序遍历右子树
		pre->rchild=NULL; //设置链表尾 
	}
	return head; 
} 

15、设计求二叉树的带权路径长度WPL的算法。(二叉树的路径长度WPL,是二叉树所有叶结点的带权路径长度之和)

(1)递归

这道题递归相对比较简单

#include <stdio.h>

/*
	思想: 
		基于递归地先序序列遍历,在此基础上多了一个判断叶结点以及多了一个深度的参数。
		并且用一个静态的变量记录wpl 
	
	步骤:
		(1)若该结点是叶结点,则变量wpl加上该结点的深度与权值之积。
		(2)若该结点是非叶结点,
				则左子树不为空时,对左子树调用递归算法;
				右子树不为空时,对右子树调用递归算法;
				深度参数均为当前层次的深度+1;
		(3)最后返回计算出的wpl即可 
*/

typedef struct BiTNode{
	int weight;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

int WPL(BiTree root){
	return wpl_PreOrder(root,0);
} 

int wpl_PreOrder(BiTreee root,int deep){
	static wpl=0;
	if(root->lchild==NULL&&root->rchild==NULL)
		wpl+=root->weight*deep;
	if(root->lchild!=NULL){
		wpl_PreOrder(root->lchild,deep+1);
	}
	if(root->rchild!=NULL){
		wpl_PreOrder(root->rchild,deep+1);
	}
	return wpl;
}

(2)层次遍历

层次遍历相对递归来说繁杂了点,但是如果层次遍历比较熟悉的话,也不是很难。其深度的判断和前面第3题的思路是一样的,就当做练习做做还是不错的。

#include <stdio.h>

/*
	思想:层次遍历的基础上,判断出队的结点是否是叶结点,若是叶结点,变量wpl加上该结点的深度与权值之积。
	(可以参考第3题,就是多了个判断叶结点,然后计算wpl而已!!) 
	
	步骤:
		(1)队列出队,当出队的结点为叶结点时,累计wpl。
		(2)若为非叶结点,则把该结点的左、右子树加入队列
		(3)接着把出队的结点和last指针比较,若两者相同则层次level+1。
		队列为空时遍历结束,返回wpl 
*/

#define MaxSize 100
typedef struct BiTNode{
	int weight;
	struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

int wpl_levelOrder(BiTree root){
	BiTree Q[MaxSize]; //声明队列,front为头指针,rear为尾指针
	int front=rear=-1; 
	int last=0; //指向当前层次最右结点,初始为根节点
	int level=0; //记录当前结点的层次
	int wpl=0; //初始化wpl 
	BiTree p; //暂存出队的结点 
	Q[++rear]=root; //根结点入队 
	while(front<rear){
		p=Q[++front]; 
		if(p->lchild==NULL&&p->rchild==NULL)
			wpl+=p->weight*level;
		if(p->lchild)
			Q[++rear]=p->lchild;
		if(p->rchild)
			Q[++rear]=p->rchild;
		if(front==last){
			level++;
			last=rear; //last指向下一层最右结点  
		}			
	}
	return wpl; 
}

16、设计一个算法,将给定的表达式树(二叉树)转化为等价的中缀表达式(通过括号反映操作符的计算次序)并输出。二叉树结点定义如下:

typedef struct node{
    char data[10];
    struct node *left,*right;
}BiTree;
#include <stdio.h>

/*
	思想:
		表达式树的中序序列加上必要的括号即为中缀表达式。
		表达式树中分支结点所对应的子表达式的计算次序,由该分支结点所处的位置决定。
		所以,需要在生成遍历序列的同时,在适当的位置添加括号。
		显然,表达式的最外层(对应根结点)和操作数(对应叶结点)时不需要添加括号的。所以函数还需要多加一个深度的参数 
		记住一点:分支结点对应表达式,叶结点对应操作数
		
	步骤:
		(1)如果是空树,返回
		(2)若为叶结点,输出操作数,不加括号
		(3)其他情况,
				若深度大于1(根结点不需要加括号),加一层左括号
				递归左子树
				输出操作符 
				递归右子树
				若深度大于1(根结点不需要加括号),加一层右括号 		 
*/ 

void BtreeToE(BiTree *root){
	BtreeToExp(root,0);
} 

void BtreeToExp(BiTree *root,int deep){
	if(root==NULL) //如果是空树,返回
		return;
	else if(root->left==NULL&&root->right==NULL) //若为叶结点,输出操作数,不加括号
		printf("%s",root->data);
	else{
		if(deep>1) //若深度大于1(根结点不需要加括号),加一层左括号
			printf("%s","(");
		BtreeToExp(root->left,deep+1); //递归左子树
		printf("%s",root->data;) //输出操作符 
		BtreeToExp(root->right,deep+1); //递归右子树
		if(deep>1) //若深度大于1(根结点不需要加括号),加一层右括号 		 
			printf("%s",")");
	}
}

17、设计一个算法,求出给定二叉排序中最小和最大的关键字

#include <stdio.h>

/*
	思想:
		利用二叉排序树的性质,左孩子结点 < 根结点 < 右孩子结点
		所以最小的关键字应该是最左下结点,最大的关键字应该是最右下结点 
*/ 

KeyType MinKey(BiTree T){
	while(T->lchild)
		T=T->lchild;
	return T->data;
}

KeyType MaxKey(BiTree T){
	while(T->rchild)
		T=T->rchild;
	return T->data;
}

18、设计一个算法,从大到小输出二叉排序树中所有值不小于k的关键字

#include <stdio.h>

/*
	思想:
		利用二叉排序树的性质,左孩子结点 < 根结点 < 右孩子结点
		所以为了从大到小输出,先遍历右子树,再访问根结点,最后遍历左子树 
*/

void OutPut(BiTree T,KeyType k){
	if(T==NULL)
		return;
	if(T->rchild)
		OutPut(T->rchild,k);
	if(T->data>=k)
		printf("%d",T->data);
	if(T->lchild)
		OutPut(T->lchild,k);
}

5、编程求以孩子兄弟表示法存储的森林的叶子结点

#include <stdio.h>


/*
	思想:
		(1)孩子兄弟表示法,第一个指针指向第一个孩子,第二个指针指向下一个兄弟结点,
		那么很显然,若结点的孩子指针为空,那它必是叶结点。
		(2)总的叶子结点个数就是孩子子树上的叶子数和兄弟子树上的叶子数 
	
	步骤:
		(1)如果树为空,返回0
		(2)如果结点的孩子指针为空,返回叶结点(个数1)和其兄弟子树中的叶结点数
			否则,返回孩子子树上的叶子数和兄弟子树上的叶子数 
*/ 

typedef struct node{
	ElemType data;
	struct node *fch, *nsib;
}*CSTree; 

int Leaves(CSTree t){
	if(t==NULL) //如果树为空,返回0
		return 0;
	if(t->fch==NULL) //如果结点的孩子指针为空,返回叶结点(个数1)和其兄弟子树中的叶结点数
		return 1 + leaves(t->nsib);
	else  //否则,返回孩子子树上的叶子数和兄弟子树上的叶子数 
		return leaves(t->fch) + leaves(t->nsib);	
}

如果觉得有帮助可以点个赞支持一下呀。

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值