设计算法统计所有单孩子结点的个数_C++二叉树计算带权路径长度(WPL)的算法...

该博客介绍了如何设计非递归和递归算法来计算二叉树的带权路径长度(WPL),其中WPL是叶子节点权值乘以其到根节点分支数的总和。通过广度优先搜索更新每个节点的分支数,并利用队列记录节点深度。同时,文章探讨了如何统计所有单孩子节点的个数。
摘要由CSDN通过智能技术生成

题目 :二叉树的带权路径长度是二叉树中所有叶子结点的带权路径长度之和。给定二叉链表的存储的结点结构为
left | weight | right

存储的是叶子结点的非负权值。设计算法求二叉树的带权路径长度WPL。WPL = ∑ 叶子结点的权值 × 结点到根结点的分支个数

例如:

50e3228463cb8026e1efd49cf4f2e733.png

非递归算法

  1. 算法思想:根据公式,需要记录每个结点到根结点的分支个数,这个过程通过对树进行广度遍历(借助队列)进行记录。
    在非叶子结点weight初值为-1,叶子结点初值设为非负权值。
    最后对队列进行逐个访问,如果weight != -1,那就计算该点。

wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1); //WPL公式代码

这里改造队列的结点结构

typedef struct {

LBTree* p; //树的结点

int lno; //结点深度

}Queue;

  1. 伪代码
typedef struct
{
	LBTree* p;
	int lno;
}Queue;
int WPL(LBTree* lbt)
{
	Queue Q[maxSize];
	int front,rear;
	front = rear = 0;
	int Lno = 1;
	LBTree* q = lbt;
	Q[rear].p = q;
	Q[rear].lno = Lno;
	rear++;
	while (front != rear)
	{
		q = Q[front].p;
		Lno = Q[front].lno;
		front++;
		if (q->lchild != NULL)
		{
			Q[rear].p = q->lchild;
			Q[rear].lno = Lno + 1;
			rear++;
		}
		if (q->rchild != NULL)
		{
			Q[rear].p = q->rchild;
			Q[rear].lno = Lno + 1;
			rear++;
		}
	}
	int wpl = 0;
	for (int i = 0; i < rear; i++)
	{	
		if (Q[i].p->weigth != -1)
			wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1);
	}
	return wpl;
}

递归算法 (推荐)

算法描述:本算法采用的是统计叶子结点算法基础上改造而来的。只是在参数列表定义了结点到根的分支个数。进行一个递归计算。

  1. 代码如下:
int WPLrec(LBTree* lbt,int n)
{
	int wpl = 0;
	if (lbt != NULL)
	{
		if (lbt->lchild == NULL && lbt->rchild == NULL)
			wpl += n * lbt->weigth;
		wpl += WPLrec(lbt->lchild, n + 1);
		wpl += WPLrec(lbt->rchild, n + 1);
	}
	return wpl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值