二叉树路径相关算法题|带权路径长度WPL|最长路径长度|直径长度|到叶节点路径|深度|到某节点的路径非递归(C)

带权路径长度WPL

二叉树的带权路径长度(WPL)是二叉树所有叶节点的带权路径长度之和,给定一棵二叉树T,采用二叉链表存储,节点结构为
在这里插入图片描述

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

算法思想

![[Pasted image 20241120144005.png]]

方法1,树中全部叶节点的带权路径长度之和
采用递归思想
二叉树的WPL值 = 树中全部叶节点的带权路径长度之和 = 根节点左子树中全部叶节点的带权路径长度之和 + 根节点右子树中全部叶节点的带权路径长度之和
叶节点的带权路径长度 = 该节点的weight域的值 x 该节点的深度
设根节点的深度为0,若某节点的深度为d,其子节点的深度为d+1
递归过程中,如果遍历到叶节点,返回该节点的带权路径长度,否则返回其左右子树的带权路径长度之和

先遍历5,d是0,不是叶子节点,递归3和7,d为1,3不是叶子节点,7是叶子节点,返回1x7,再递归1和4,d为2,都是叶子节点,返回1x2和4x2,所以WPL为2+8+7=17

typedef struct node
{
   
   
	int weight;
	struct node *left, *right;
}BTNode;

// 传入根节点,调用递归函数,初始深度d为0
int WPL(BTNode* root)
{
   
   
	return WPL1(root, 0);
}

// 传入节点和该节点的深度
int WPL1(BTNode* root, int d)
{
   
   
	// 如果该节点是叶子节点,返回该叶子节点的weightxd,也就是带权路径长度
	if (root->left == NULL && root->right == NULL)
		return (root->weight * d);
	// 否则递归该节点的左孩子和右孩子,子节点的深度为根节点的深度+1
	else
		return (WPL1(root->left, d + 1) + WPL1(root->right, d + 1));
}

WPL1是一个递归函数,用来计算从当前节点开始的WPL

最长路径长度

给定一个二叉树的root,返回最长的路径的长度,这个路径中的每个节点具有相同值。这条路径可以经过也可以不经过根节点。两个节点之间的路径的长度由它们之间的边数表示

算法思想

符合要求的左子树路径最大长度leftpath,符合要求的右子树路径最大长度rightpath,最后的路径长度为当前路径,与rightpath+leftpath最大值,注意全局变量的初始化位置
![[Pasted image 20241120204702.png]]

第一层
递归计算root的左右孩子的最长单向路径
右节点存在且与当前节点值相等,都是5
rightpath = right+1
![[Pasted image 20241120205655.png]]

第二层
right是右节点的DFS返回的值;
递归计算这个节点的左右孩子的最长单向路径,
同样右节点存在且与当前值相等,都是5
rightpath = right+1
![[Pasted image 20241120205727.png]]

第三层
right是右孩子返回的值,
递归左右孩子,为空,返回0
left和right都是0,path也是0,最后返回0
返回第二层
right是0,rightpath是1,path更新为1,返回1
返回第一层
right是1,rightpath是2,path更新为2,返回2

int path;   // 全局变量,用于存储当前发现的最长路径长度
// 返回两个正数中的较大值
int Max(int a, int b)
{
   
   
	return a >= b ? a : b;
}
// 递归地计算以root为根的子树中,以相同节点值构成的最长路径
int DFS(BTNode* root)
{
   
   
	// 如果当前节点为空,返回0,因为没有路径
	if (root == NULL)
		return 0;

	int left;
	int right;
	int leftpath = 0;
	int rightpath = 0;
	// 递归计算左子树和右子树的最长单向路径
	// left是左子树的最长路径,right是右子树的最长路径
	left = DFS(root
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值