You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

关于二叉搜索树(BST)内部路径长度(IPL)计算函数结果不准确的问题咨询

问题分析与修复方案

嘿,你的代码在树层级超过2级时IPL计算出错,咱们来一步步拆解问题,然后给出符合你预期的修复方案:

先明确你的IPL定义

首先看你给出的测试案例:插入10、5、15、30后,正确IPL值为8。这个值对应的是所有节点到根节点的路径上的节点数之和(也就是节点深度之和)

  • 根节点10深度为1
  • 5和15深度为2
  • 30深度为3
    总和:1+2+2+3=8

(注:标准的二叉树内部路径长度IPL是所有节点到根的路径边数之和,对应这个案例的话是0+1+1+2=4,但显然你要的是前者的计算结果)

核心问题拆解

1. 全局变量count的滥用

这个全局变量是最大的坑:

  • 它不会在每次调用getIPL前重置,导致多次调用时会在旧值基础上累加错误结果;
  • 递归处理左右子树时,count的修改逻辑混乱,比如处理左子树后count已经被修改,处理右子树时会继续叠加,导致深层级节点的贡献被重复计算。

2. getIPL的计算逻辑错误

原函数的递归逻辑完全不符合你需要的深度之和计算:

  • 叶子节点直接把count设为1,忽略了叶子节点的实际深度;
  • 递归返回的count是全局累加值,不是当前子树的深度贡献,导致父节点计算时叠加错误数值。

修复后的代码

下面的代码完全去掉全局变量,用递归传递当前节点深度的方式,准确计算所有节点的深度之和:

#include <stdio.h>
#include <stdlib.h>

typedef struct treeNode {
    int key;
    struct treeNode* left;
    struct treeNode* right;
} treeNode;

treeNode* insertNode(treeNode** t1, int x) {
    if (*t1 == NULL) {
        *t1 = malloc(sizeof(treeNode));
        (*t1)->key = x;
        (*t1)->left = NULL;
        (*t1)->right = NULL;
    } else if (x < (*t1)->key) { // 插入左子树
        (*t1)->left = insertNode(&(*t1)->left, x);
    } else if (x > (*t1)->key) { // 插入右子树
        (*t1)->right = insertNode(&(*t1)->right, x);
    } else {
        printf("SameValue exist.\n");
    }
    return *t1;
}

// 辅助递归函数:传递当前节点的深度,累加所有节点的深度之和
int calculateDepthSum(treeNode* node, int currentDepth) {
    if (node == NULL) {
        return 0;
    }
    // 当前节点深度 + 左子树所有节点深度之和 + 右子树所有节点深度之和
    return currentDepth + calculateDepthSum(node->left, currentDepth + 1) + calculateDepthSum(node->right, currentDepth + 1);
}

// 对外调用的IPL计算函数,根节点初始深度为1
int getIPL(treeNode* root) {
    return calculateDepthSum(root, 1);
}

int main() {
    treeNode* T1 = NULL;
    // 测试案例1:10、5、15
    insertNode(&T1, 10);
    insertNode(&T1, 5);
    insertNode(&T1, 15);
    printf("IPL (10,5,15): %d\n", getIPL(T1)); // 输出5,符合预期
    
    // 插入30后测试
    insertNode(&T1, 30);
    printf("IPL (add 30): %d\n", getIPL(T1)); // 输出8,符合你的正确值
    return 0;
}

代码说明

  • 去掉了全局变量count,改用递归时传递当前节点的深度,避免了全局状态的干扰;
  • 递归逻辑清晰:每个节点的贡献是自身深度,加上左右子树所有节点的深度之和;
  • 完全符合你给出的测试案例预期:插入10、5、15后输出5,插入30后输出8。

内容的提问来源于stack exchange,提问作者Hyeonbinshin

火山引擎 最新活动