【数据结构】二叉树的带权路径长度WPL是二叉树中所有叶结点的带权路径长度之和。给定一颗二叉树T,采用二叉链表存储,结点结构为:

题1:二叉树的带权路径长度WPL是二叉树中所有叶结点的带权路径长度之和。给定一颗二叉树T,采用二叉链表存储,结点结构为:

leftweightright

其中叶结点的weight域保存该结点的非负权值。设root为指向T的根结点的指针,请设计求T的WPL的算法。

要求:
1)给出算法的基本设计思想
2)使用C或C++语言,给出二叉树结点的数据类型定义
3)根据设计思想,采用C或C++描述算法
4)给出该算法的时间复杂度
 

一、算法的设计思想

1.理解二叉树的带权路径长度

树中所有叶子结点的带权路径长度之和,记作:

WPL=w1×l1+w2×l2+⋯+wn×ln=∑wi×li(i=1,2,⋯,n)。

n为叶子结点的个数,wi为第i个结点的权值,即其数据域,li为第i个结点的路径长度。

2.求二叉树的带权路径长度示例

 a.WPL=7×2+5×2+2×2+4×2=36

 b.WPL=7×3+5×3+4×2+2×1=46

c.WPL=7×1+5×2+2×3+4×3=35

3.模拟算法求二叉树的带权路径长度WPL

(1)采用递归算法实现。

(2)二叉树的WPL值=树中全部叶结点的带权路径长度之和=根结点左子树中全部叶结点的带权路径长度之和+根结点右子树中全部叶结点的带权路径长度之和。

(3)叶结点的带权路径长度=该结点的weight域的值×该结点的深度

(4)设根结点的深度为0,若某结点的深度为d时,则其孩子结点的深度为d+1。

4.核心算法思想:

采用先序递归遍历

(1)声明一个sum变量,用来叠加存放每个叶节点加权值的和。用static对其进行修饰,sum变量的生命周期延长到程序执行结束时,离开定义它的WPL函数后不能使用,但如再次调用WPL函数时,它可继续使用,而且保存了前次被调用后留下的值。适用于在此递归算法中求和;

(2)第一个if分支当前结点没有左右子结点的时候,说明它已经是叶节点了,所以直接将其结点数据域×深度+sum,计算当前及之前叶节点的带权总和。该分支也是递归的出口;

(3)第二个if分支,若该结点是非叶节点,左子树不为空时,对左子树调用递归算法,深度参数在本结点的深度参数上加1;

(4)第三个if分支,右子树不为空时,对右子树调用递归算法,深度参数在本结点的深度参数上加1。

当上述分支都递归进入了第一分支的情况后,即求得了所有的叶节点带权值之和,算法结束。

二、二叉树结点数据类型定义

typedef struct Tree
{
    int weight;					             //	存放数据域
    struct Tree *leftchild;			          //	遍历左子树指针
    struct Tree *rightchild;			          //	遍历右子树指针
} Tree,*BitTree;

三、描述算法

核心算法代码:

int WPL(Tree *root,int deep)
{
    static long sum=0;
    if(root->leftchild == NULL && root->rightchild==NULL) 
//若为叶结点,累积求和
        sum+=deep*root->weight;
    if(root->leftchild!=NULL)               //若左子树不空,对左子树递归遍历
        WPL(root->leftchild,deep+1);
    if(root->rightchild!=NULL)              //若右子树不空,对右子树递归遍历
        WPL(root->rightchild,deep+1);
    return sum;
}

四、算法时间复杂度

WPL算法采用了分治思想,将其整棵树的带权和转换为根节点左右两个子树的带权和再相加,以此递归进行。但是这个分治有别于快速排序归并排序等,快速排序的n是数组长度,在排序过程中有重复访问,所以这种情况下时间复杂度为O(nlogn)。但是WPL算法是对左右子树进行访问,n个结点每个结点只访问一次,它访问到叶结点即求出带权和之后,直接到了递归出口,接着开始另外的结点遍历,不存在重复遍历的情况。

基于以上分析可以得到算法时间复杂度为O(n)

  • 9
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值