二叉树宽度高度相关算法题|非递归求二叉树高度|求非空二叉树宽度(C)

非递归求二叉树高度

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

算法思想

采用层次遍历的算法,设置遍历level记录当前节点所在的层数,设置变量last指向当前层的最右节点,每次层次遍历出队时与last指针比较,若两者相等,则层数+1,并让last指向下一层的最右节点,直到遍历完成。level的值即为二叉树的高度

如果是空树,高度为0,返回0
初始化front和rear数组队列下标指针
初始化last指向队列中的最右节点,level表示层数
创建一个数组,数据类型是二叉树节点,大小是MaxSize
![[Pasted image 20241119090953.png]]

front和rear初始化为-1,表示队列为空,
rear指向队尾最后一个节点,front指向队头节第一个节点的前一个位置
将根节点入队,先++rear,再把T赋值进去
![[Pasted image 20241119091118.png]]

创建一个工作指针cur访问节点
队列元素出队,即++front,用cur指向出队元素
![[Pasted image 20241119093141.png]]

将当前节点的左孩子右孩子入队
![[Pasted image 20241119093412.png]]

当前front是0,last也是0,front指向的是上一层的最右节点A,last初始化为0,也就是指向A,表示是最右节点,
层数level+1
因为是层序遍历,所以rear指向的就是当前层的最右节点
last指向rear,也就是下一层,指向C
然后继续出队遍历,
![[Pasted image 20241119094158.png]]

front指向的出队元素B不是最右元素,继续出队
![[Pasted image 20241119094215.png]]

front等于last,level++,last指向rear也就是E
继续出队
![[Pasted image 20241119094302.png]]

出到E,front等于last,level++

int BTdepth(BTNode* T)
{
	if (!T)
		// 树空,高度为0
		return 0;

	int front = -1, rear = -1;
	// last指向当前层的最右节点
	int last = 0, level = 0;
	// 设置队列Q,元素是二叉树节点指针且容量足够
	BTNode Q[MaxSize];
	// 将根节点入队
	Q[++rear] = T;
	BTNode* cur;
	// 队不空则循环
	while (front < rear)
	{
		// 队列元素出队,即正在访问的节点
		cur = Q[++front];
		if (cur->left)
			// 左孩子入队
			Q[++rear] = cur->left;
		if (cur->right)
			// 右孩子入队
			Q[++rear] = cur->right;
		// 处理该层的最右节点
		if (front == last)
		{
			// 层数加1
			level++;
			// last指向下一层
			last = rear;
		}
	}
	return level;
}

求非空二叉树宽度

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

算法思想

采用层次遍历的方法求出所有节点的层次,并将所有节点和对应的层次放在一个队列中
然后通过扫描队列求出各层的节点总数,最大的层节点总数即为二叉树的宽度
![[Pasted image 20241119135323.png]]

rear++,根节点入队,指针赋给data里的rear下标的位置,层次赋给level里的rear下标的位置
![[Pasted image 20241119135445.png]]

出队,front++,把出队节点,也就是data和level的front下标位置的数据读出来,保存到cur和lv
把左右孩子读进去,把节点和层次也存到相应位置,
![[Pasted image 20241119140153.png]]

![[Pasted image 20241119140933.png]]

直到队空循环结束
![[Pasted image 20241119141018.png]]

用i遍历整个队列
![[Pasted image 20241119141331.png]]

用n统计第lv层的节点个数
lv初始化为1,也就是查找第一层的节点,也就是level数组,如果level的i下标的值等于level表示有一个节点,n++
走完之后,lv等于最后一次i++的下标位置的值,也就是2
![[Pasted image 20241119141356.png]]

然后再开始一轮,
最后max=2

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

int BTWidth(BTNode* T)
{
	BTNode* = cur;
	int lv, max, i, n;
	// front=rear=-1,队列为空
	Que.front = Que.rear = -1;
	// 根节点入队
	Que.rear++;
	Que.data[Que.rear] = T;
	// 根节点层次为1
	Que.level[Que.rear] = 1;
	// 当队列不为空
	while (Que.front < Que.rear)
	{
		// 出队
		Que.front++;
		// 读取出队节点
		cur = Que.data[Que.front];
		// 保存出队节点的层次
		lv = Que.level[Que.front];
		// 左孩子进队列
		if (cur->left)
		{
			Que.rear++;
			// 进保存指针的数组
			Que.data[Que.rear] = cur->left;
			// 进保存层次的数组
			Que.level[Que.rear] = lv + 1;
		}
		// 右孩子进队列
		if (cur->right)
		{
			Que.rear++;
			Que.data[Que.rear] = cur->right;
			Que.level[Que.rear] = lv + 1;
		}
	}
	// max保存同一层最多的节点个数
	max = 0;
	i = 0;
	// lv表示从第一层开始找
	lv = 1;
	// i扫描队中的所有元素
	while (i <= Que.rear)
	{
		// n统计第lv层的节点个数
		n = 0;
		while (i <= Que.rear && Que.level[i] == lv)
		{
			n++;
			i++;
		}
		lv = Que.level[i];
		// 保存最大的n
		if (n > max)
			max = n;
	}
	return max;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值