二叉树节点相关算法题|双分支节点个数|所有左叶子之和|每一层节点平均值(C)

双分支节点个数

假设二叉树采用二叉链表存储结构存储,试设计一个算法,计算一棵给定二叉树的所有双分支节点个数

算法思想

计算一棵二叉树中所有双分支节点个数的递归模型
若树为空,结果为0
若当前节点为双分支节点,递归左右孩子,并且+1
若是其他情况,当前节点是单分支节点或叶节点

int DsonNode(BTNode* root)
{
	BTNode* cur = root;
	if (cur == NULL)
		// 空树返回0
		return 0;
	// 判断当前节点是否有两个子节点
	if (cur->left != NULL && cur-right != NULL)
		// 计数+1
		return DsonNode(cur->left) + DsonNode(cur->right) + 1;
	else
		// 不符合条件,仅递归左右子树
		return DsonNode(cur->left) + DsonNode(cur->right);
}

所有左叶子之和

计算给定二叉树的所有左叶子之和

算法思想
  • 递归遍历树:
    • 从根节点出发,沿着树的左右分支递归访问所有节点。
    • 递归过程中,判断每个节点是否为左叶子节点。
  • 累加左叶子节点的值:
    • 如果节点满足条件,则将其值累加到最终结果中。
      递归所有节点,先标记左节点,flag=true,然后如果满足条件,也就是左右孩子为空,即是左叶子节点
int leaf(BTNode* root, bool flag)
{
	if (root == NULL)
		return 0;
	// 如果是左叶子节点
	if (flag == true && root->left == NULL && root->right == NULL)
		return root->val;
	// 递归处理左右子树
	return leaf(root->left, true) + leaf(root->right, false);
}
int sumOfLeftLeaves(BTNode* root)
{
	if (root == NULL)
		return 0;
	return leaf(root, false);
}
  1. 函数 leaf:
    • 参数说明:
      • BTNode root:当前节点。
      • bool flag:标志变量,指示当前节点是否是左子节点。
    • 功能:
      • 如果当前节点为空,返回 0。
      • 如果当前节点是左叶子节点(即 flag == true 且没有左、右子节点),返回该节点的值。
      • 否则递归计算左子树和右子树的结果,分别传递 true 和 false 给左子树和右子树。
    • 返回值:所有符合条件的左叶子节点值的和。
  2. 函数 sumOfLeftLeaves:
    • 参数说明:
      • BTNode* root:树的根节点。
    • 功能:
      • 如果根节点为空,直接返回 0。
      • 调用辅助函数 leaf,从根节点开始递归计算。
    • 返回值:整棵树中左叶子节点的值的总和。

每一层节点平均值

给定一个非空二叉树的根节点root,以数组的形式返回每一层节点的平均值

算法思想

使用深度优先搜索计算二叉树的层平均值,需要维护两个数组,counts数组用于存储二叉树的每一层的节点数,sums用于存储二叉树的每一层的节点值之和。
搜索过程中需要记录当前节点所在层,如果访问到的节点在第i层,则将counts的i的值+1,并将该节点值加到sums的i。
遍历结束之后,第i层的平均值即为sums的i除以counts的i

  • 深度优先搜索(DFS):
    • 遍历树的每一层,将每层的节点值累计到对应的数组中。
    • 同时记录每层的节点个数。
  • 结果计算:
    • 遍历存储的总和值和节点个数,计算每层的平均值。
      ![[Pasted image 20241210230316.png]]
  1. 初始的时候
    counts数组和sums数组都是0,countsSize和sumsSize表示当前数组的有效大小,也是0
    level当前层级也是0
  2. 访问根节点
    当前level是0,level不小于sumsSize,表示当前层未初始化
    初始化新层,sum[0] = 5.0, cuonts[0] = 1
    更新有效层数,countsSize = 1, sumsSize = 1
  3. 访问节点6
    当前level是1,level不小于sumsSize,表示当前层未初始化
    初始化新层,sum[1] = 6.0, cuonts[1] = 1
    更新有效层数,countsSize = 2, sumsSize = 2
  4. 访问节点3
    当前level是1,level小于sumsSize,表示当前层已初始化
    更新当前层,sum[1] = 9.0, cuonts[1] = 2
  5. 访问节点2
    当前level是2,level不小于sumsSize,表示当前层未初始化
    初始化新层,sum[2] = 2.0, cuonts[2] = 1
    更新有效层数,countsSize = 3, sumsSize = 3
  6. 访问节点8
    当前level是2,level小于sumsSize,表示当前层已初始化
    更新当前层,sum[2] = 10.0, cuonts[2] = 2
  7. 访问节点7
    当前level是2,level小于sumsSize,表示当前层已初始化
    更新当前层,sum[2] = 17.0, cuonts[2] = 3
int countsSize;
int sumsSize;

void dfs(struct BTNode* root, int level, int* counts, double* nums)
{
	if (root == NULL)
		return 0;
	// 如果超过当前最大层数,初始化新层
	if (level < sumsSize)
	{
		sums[level] += root->val;
		counts[level] += 1;
	}
	else
	{
		sums[sumsSize++] = (double)root->val;
		counts[countsSize++] = 1;
	}
	// 递归访问左右子树
	dfs(root->left, level + 1. counts, sums);
	dfs(root->right, level + 1. counts, sums);
}
double* averageOfLevels(BTNode* root)
{
	countsSize = sumsSize = 0;
	int* counts = malloc(sizeof(int) * 1001);
	double* sums = malloc(sizeof(double) * 1001);
	// 深度优先搜索
	dfs(root, 0, counts, sums);
	// 计算每层的平均值
	double* averages = malloc(sizeof(double) * 1001);
	for (int i = 0; i < sumsSize; i++)
	{
		averages[i] = sums[i] / counts[i];
	}
	return averages;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值