C++二叉树计算带权路径长度(WPL)的算法

二叉树计算带权路径长度(WPL)的算法

更多内容请访问点击我的主页

题目 :

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

left weight right

weight存储的是叶子结点的非负权值。设计算法求二叉树的带权路径长度WPL。

WPL = ∑ 叶子结点的权值 × 结点到根结点的分支个数 1

例如:
在这里插入图片描述

非递归算法

  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. 算法描述:本算法采用的是统计叶子结点算法基础上改造而来的。只是在参数列表定义了结点到根的分支个数。进行一个递归计算。统计结点数在个人主页有相关算法。
  2. 代码如下:
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;
}

  1. 结点到根结点的分支个数 = 该结点的深度 - 1。 ↩︎

发布了16 篇原创文章 · 获赞 25 · 访问量 1135

猜你喜欢

转载自blog.csdn.net/weixin_41546300/article/details/102879137
今日推荐