求二叉树的深度、宽度和叶子结点数

57 篇文章 1 订阅
52 篇文章 2 订阅

如果用链表来存储二叉树,那么可以将二叉树定义如下:

typedef char ElemType;
typedef struct node{
	ElemType data;     //数据元素
	struct node* lchild;  //指向左孩子
	struct node* rchild;  //指向右孩子
}BTNode;

问题一:二叉树的深度
  二叉树的深度,也叫二叉树的高度,二叉树的深度等于从根结点到叶子结点的最长路径加1。用递归的观点来看,二叉树的深度,等于其最大左右子树的深度加1,而每个左子树(右子树)又可以分解为次左子树+次右子树,它们是深度也是最大子树深度加1。也就是二叉树深度的递归模型f(b)如下:     { f ( b ) = 0 , 若b=NULL f ( b ) = M a x { f ( b − > l c h i d ) , f ( b − > r c h i l d ) } + 1 , 其他情况          \begin{cases} f(b)=0, & \text{若b=NULL} \\ f(b)=Max\{f(b->lchid),f(b->rchild)\}+1, & \text{其他情况}  \end{cases}      {f(b)=0,f(b)=Max{f(b>lchid),f(b>rchild)}+1,b=NULL其他情况    

对应的递归算法如下:

//求二叉树b的深度
int BTNodeDepth(BTNode *b){
	int lchilddep,rchilddep;
	if(b==NULL)
		return 0;
	else{
		lchilddep=BTNodeDepth(b->lchild);
		rchilddep=BTNodeDepth(b->rchild);
		return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
	}

}

问题二:二叉树的宽度
  二叉树的宽度:具有结点数最多的那一层的结点个数。
  采用分层遍历的方法求出所有结点的层编号,然后,求出各层的结点总数,通过比较找出层结点数最多的值。对应的算法如下:

//求二叉树b的宽度
int BTWidth(BTNode *b){
	struct{
		int lno;        //结点的层次编号
		BTNode *p;      //结点指针
	}Qu[MaxSize];      //定义顺序非循环队列
	int front,rear;
	int lnum,max,i,n;
	front=rear=0;      //置队列为空
	if (b!=NULL)
	{
		rear++;
		Qu[rear].p=b;      //根结点指针入队
		Qu[rear].lno=1;    //根结点的层次编号为1
		while (rear!=front)  //队列不为空
		{
			front++;
			b=Qu[front].p;    //队头出队
			lnum=Qu[front].lno;
			if (b->lchild!=NULL)  //左孩子入队
			{
				rear++;
				Qu[rear].p=b->lchild;
				Qu[rear].lno=lnum+1;
			}
			if (b->rchild!=NULL)  //右孩子入队
			{
				rear++;
				Qu[rear].p=b->rchild;
				Qu[rear].lno=lnum+1;
			}
		}
		max=0; lnum=1; i=1;
		while (i<=rear)
		{
			n=0;
			while (i<=rear && Qu[i].lno==lnum)
			{
				n++; i++;
			}
			lnum=Qu[i].lno;
			if(n>max) max=n;
		}
		return max;
	}
	else
		return 0;

}

问题三:二叉树b的叶子结点个数
  当b为空树时,叶子结点数为0;
  当b的左子树和右子树都为空,b只有一个结点时,叶子结点数为1;
  当b的左子树或右子树不为空时,叶子结点数=左子树叶子结点数+右子树叶子结点数。
  即递归模型为:

{ f ( b ) = 0 , 若b=NULL f ( b ) = 1 , 若b->lchild==NULL且b->rchild==NULL f ( b ) = f ( b − > l c h i l d ) + f ( b − > r c h i l d ) , 其他情况 \begin{cases} f(b)=0, & \text{若b=NULL} \\ f(b)=1, & \text{若b->lchild==NULL且b->rchild==NULL} \\ f(b)=f(b->lchild)+f(b->rchild), & \text{其他情况} \end{cases} f(b)=0,f(b)=1,f(b)=f(b>lchild)+f(b>rchild),b=NULLb->lchild==NULLb->rchild==NULL其他情况

对应的递归算法如下:

//求二叉树b的叶子结点个数
int LeafNodes(BTNode *b){
	int num1,num2;
	if(b==NULL)
		return 0;
	else if(b->lchild==NULL && b->rchild==NULL)
		return 1;
	else{
		num1=LeafNodes(b->lchild);
		num2=LeafNodes(b->rchild);
		return (num1+num2);
	}

}

完整代码如下:

//BinaryTreeBase.h
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct node{
	ElemType data;     //数据元素
	struct node* lchild;  //指向左孩子
	struct node* rchild;  //指向右孩子
}BTNode;

//由str串创建二叉链
void CreateBTNode(BTNode *&b,char *str){
	BTNode *St[MaxSize],*p=NULL;
	int top=-1,k,j=0;
	char ch;
	b=NULL;
	ch=str[j];
	while (ch!='\0')
	{
		switch(ch){
		case '(': top++; St[top]=p; k=1; break;
		case ')': top--; break;
		case ',': k=2; break;
		default: p=(BTNode *)malloc(sizeof(BTNode));
			p->data=ch; p->lchild=p->rchild=NULL;
			if(b==NULL)
				b=p;
			else{
				switch(k){
				case 1: St[top]->lchild=p; break;
				case 2: St[top]->rchild=p; break;
				}
			}
		}
		j++;
		ch=str[j];
	}

}

//返回data域为x的结点指针
BTNode *FindNode(BTNode *b,ElemType x){
	BTNode *p;
	if(b==NULL)
		return NULL;
	else if(b->data==x)
		return b;
	else{
		p=FindNode(b->lchild,x);
		if(p!=NULL)
			return p;
		else
			return FindNode(b->rchild,x);
	}

}

BTNode *LchildNode(BTNode *p){
	return p->lchild;
}

BTNode *RchildNode(BTNode *p){
	return p->rchild;
}

//求二叉树b的深度
int BTNodeDepth(BTNode *b){
	int lchilddep,rchilddep;
	if(b==NULL)
		return 0;
	else{
		lchilddep=BTNodeDepth(b->lchild);
		rchilddep=BTNodeDepth(b->rchild);
		return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);
	}

}

//用括号表示法输出二叉树
void DispBTNode(BTNode *b){
	if (b!=NULL)
	{
		printf("%c",b->data);
		if (b->lchild!=NULL || b->rchild!=NULL)
		{
			printf("(");
			DispBTNode(b->lchild);
			if(b->rchild!=NULL) printf(",");
			DispBTNode(b->rchild);
			printf(")");
		}
	}

}

void printBTN(BTNode *b,int w){
	int i;
	if (b!=NULL)
	{
		printBTN(b->rchild,w+5);
		for(i=1;i<w;i++)
			printf(" ");
		printf("%c\n",b->data);
		printBTN(b->lchild,w+5);
	}

}

//求二叉树b的宽度
int BTWidth(BTNode *b){
	struct{
		int lno;        //结点的层次编号
		BTNode *p;      //结点指针
	}Qu[MaxSize];      //定义顺序非循环队列
	int front,rear;
	int lnum,max,i,n;
	front=rear=0;      //置队列为空
	if (b!=NULL)
	{
		rear++;
		Qu[rear].p=b;      //根结点指针入队
		Qu[rear].lno=1;    //根结点的层次编号为1
		while (rear!=front)  //队列不为空
		{
			front++;
			b=Qu[front].p;    //队头出队
			lnum=Qu[front].lno;
			if (b->lchild!=NULL)  //左孩子入队
			{
				rear++;
				Qu[rear].p=b->lchild;
				Qu[rear].lno=lnum+1;
			}
			if (b->rchild!=NULL)  //右孩子入队
			{
				rear++;
				Qu[rear].p=b->rchild;
				Qu[rear].lno=lnum+1;
			}
		}
		max=0; lnum=1; i=1;
		while (i<=rear)
		{
			n=0;
			while (i<=rear && Qu[i].lno==lnum)
			{
				n++; i++;
			}
			lnum=Qu[i].lno;
			if(n>max) max=n;
		}
		return max;
	}
	else
		return 0;

}

//求二叉树b的结点个数
int Nodes(BTNode *b){
	int num1,num2;
	if(b==NULL)
		return 0;
	else if(b->lchild==NULL && b->rchild==NULL)
		return 1;
	else{
		num1=Nodes(b->lchild);
		num2=Nodes(b->rchild);
		return (num1+num2+1);
	}

}

//求二叉树b的叶子结点个数
int LeafNodes(BTNode *b){
	int num1,num2;
	if(b==NULL)
		return 0;
	else if(b->lchild==NULL && b->rchild==NULL)
		return 1;
	else{
		num1=LeafNodes(b->lchild);
		num2=LeafNodes(b->rchild);
		return (num1+num2);
	}

}

//主函数.cpp
#include "BinaryTreeBase.h"
#include <stdio.h>
#include <stdlib.h>

void main()
{
	BTNode* bt;
	char str[20]="A(B(D(,G)),C(E,F))";
	CreateBTNode(bt,str);
	printf("二叉树的括号表示法:");
	DispBTNode(bt);
	printf("\n");

	printf("横向打印二叉树:\n");
	printBTN(bt,10);
	printf("\n");

	int num=0,leafNum=0,deepth=0,width=0;
	num=Nodes(bt);
	leafNum=LeafNodes(bt);
	deepth=BTNodeDepth(bt);
	width=BTWidth(bt);

	printf("二叉树的结点数: %d\n",num);
	printf("二叉树的叶子结点数: %d\n",leafNum);
	printf("二叉树的深度: %d\n",deepth);
	printf("二叉树的宽度: %d\n",width);

	system("pause");
}

效果如下:

图(1) 用括号表示法,创建二叉树,并求它的深度、宽度和叶子结点数
图(1) 用括号表示法,创建二叉树,并求它的深度、宽度和叶子结点数

  • 9
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是关于创建二叉树二叉树叶子节点二叉树深度的回答: 1. 创建二叉树 创建二叉树的方法有很多,这里提供一种基于Python的实现方法。我们可以定义一个二叉树节点类,然后通过递归的方式创建二叉树。 ```python class TreeNode: def __init__(self, val=0, left=None, right=None): self.val = val self.left = left self.right = right def create_tree(nums): if not nums: return None mid = len(nums) // 2 root = TreeNode(nums[mid]) root.left = create_tree(nums[:mid]) root.right = create_tree(nums[mid+1:]) return root ``` 上述代码中,我们定义了一个TreeNode类,包含节点值val、左子节点left和右子节点right。create_tree函接收一个列表nums作为参,返回一个二叉树的根节点。在函内部,我们首先判断nums是否为空,如果为空则返回None。否则,我们找到nums的中间位置mid,将mid位置的元素作为根节点的值,然后递归地创建左子树和右子树。 2. 二叉树叶子节点 二叉树叶子节点是指没有子节点节点。我们可以通过递归的方式遍历整个二叉树,统计叶子节点的个。 ```python def count_leaves(root): if not root: return 0 if not root.left and not root.right: return 1 return count_leaves(root.left) + count_leaves(root.right) ``` 上述代码中,count_leaves函接收一个二叉树的根节点root作为参,返回二叉树叶子节点。在函内部,我们首先判断root是否为空,如果为空则返回0。然后判断root是否为叶子节点,如果是则返回1。否则,递归地计算左子树和右子树的叶子节点,并将它们相加。 3. 二叉树深度 二叉树深度是指从根节点到最远叶子节点的最长路径上的节点。我们可以通过递归的方式遍历整个二叉树,统计二叉树深度。 ```python def max_depth(root): if not root: return 0 left_depth = max_depth(root.left) right_depth = max_depth(root.right) return max(left_depth, right_depth) + 1 ``` 上述代码中,max_depth函接收一个二叉树的根节点root作为参,返回二叉树深度。在函内部,我们首先判断root是否为空,如果为空则返回0。然后递归地计算左子树和右子树的深度,并将它们的最大值加1返回。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值