考研数据结构(每日一题)day40

考研数据结构(每日一题)

题目:二叉树的带权路径长度(WPL)是二叉树中所有叶结点的带权路径长度之和,给定一棵二叉树T,采用二叉链表存储,结点结构为(left,weight,right),其中叶结点的weight域保存该结点的非负权值,设root为指向T的根结点的指针,请设计求T的WPL的算法。

算法思想:

二叉树的带权路径长度为每个叶结点的深度与权值之和的总和,可以使用先序遍历层次遍历。

先序遍历使用一个static变量记录wpl,把每个结点的深度作为递归函数的一个参数传递。

  • 若该结点是叶结点,则变量wpl加上该结点的深度与权值之积
  • 若该结点非叶结点,则左子树不为空时,对左子树调用递归算法,右子树不为空,对右子树调用递归算法,深度参数均为结点的深度加1
  • 最后返回计算wpl即可

层次遍历是使用队列,并记录当前的层数

  • 当遍历到叶结点时,累计wpl
  • 当遍历到非叶结点时,把该结点的子树加入队列
  • 当某结点为该层最后一个结点时,层数自增加1
  • 队空时,遍历结束,返回wpl

完整代码:

先序遍历:

typedef struct BiTNode{
    int weight;
    struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int WPL(BiTree root){
    return wpl_PreOrder(root,0);
}
int wpl_PreOrder(BiTree root,int deep){
    static int wpl = 0;   //定义变量存储wpl
    if(root -> lchild == NULL && root -> rchild == NULL){  //若为叶结点,则累计wpl
        wpl += deep * root  -> weight;
    }
    if(root -> lchild != NULL){  //若左子树不空,则对左子树递归
        wpl_PreOrder(root -> lchild,deep + 1);
    }
    if(root -> rchild != NULL){  //若右子树不空,则对右子树递归
        wpl_PreOrder(root -> rchild,deep + 1);
    }
    return wpl;
}

层次遍历:

# define MaxSize 100  //设置队列最大容器
int wpl_LevelOrder(BiTree root){
    BiTree q[MaxSize];   //声明队列
    int end1,end2;   //end1为头指针,end2为尾指针,队列最多容纳MaxSize-1个元素
    end1 = end2 = 0;   //头指针指向队头元素,尾指针指向队尾的后一个元素
    int wpl = 0,deep = 0;   //初始化wpl和深度
    BiTree lastNode;    //lastNode记录当前层的最后一个结点
    BiTree newlastNode;  //newlastNode用来记录下一层的最后一个结点
    lastNode = root;   //lastNode初始化为根结点
    newlastNode = NULL; //初始化为空
    q[end2 ++] = root;  //根结点入队
    while (end1 != end2)  //层次遍历,若队列不空则循环
    {
        BiTree t = q[end1 ++];  //拿出队列中的头一个元素
        if(t -> lchild == NULL && t -> rchild == NULL){
            wpl += deep * t -> weight;
        }
        if(t -> lchild != NULL){  //若非叶结点,则让左结点入队
            q[end2 ++] = t -> rchild;
            newlastNode = t -> lchild;
        }   //并设下一层的最后一个结点为该结点的左结点
        if(t -> rchild != NULL){  //处理叶结点
            q[end2 ++] = t -> rchild;
            newlastNode = t -> rchild;
        }
        if(t == lastNode){  //若该结点为本层最后一个结点,则更新lastNode
            lastNode = newlastNode;
            deep += 1;  //层数加1
        }
    }
    return wpl;  //返回
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值