题目 :二叉树的带权路径长度是二叉树中所有叶子结点的带权路径长度之和。给定二叉链表的存储的结点结构为
left | weight | right
存储的是叶子结点的非负权值。设计算法求二叉树的带权路径长度WPL。WPL = ∑ 叶子结点的权值 × 结点到根结点的分支个数
例如:
非递归算法
- 算法思想:根据公式,需要记录每个结点到根结点的分支个数,这个过程通过对树进行广度遍历(借助队列)进行记录。
在非叶子结点weight初值为-1,叶子结点初值设为非负权值。
最后对队列进行逐个访问,如果weight != -1,那就计算该点。
wpl += (Q[i].p->weigth) * (Q[i].p->lno - 1); //WPL公式代码
这里改造队列的结点结构
typedef struct {
LBTree* p; //树的结点
int lno; //结点深度
}Queue;
- 伪代码
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;
}
递归算法 (推荐)
算法描述:本算法采用的是统计叶子结点算法基础上改造而来的。只是在参数列表定义了结点到根的分支个数。进行一个递归计算。
- 代码如下:
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;
}