内部路径长度功能的问题

时间:2015-10-04 03:31:06

标签: c++ tree binary-search-tree avl-tree

我被要求在二叉搜索树和AVL树中计算节点的平均深度。通过一些研究,我发现树的平均深度是内部路径长度除以树中节点的数量,并且给出内部路径长度(树中每个节点的路径长度的总和)通过这种复发:

D(1) = 0, D(N) = D(i) + D(N − i − 1) + N − 1

其中D(N)是具有N个节点的树,D(i)是左子树的IPL,D(N-i-1)是右子树的IPL。

使用它,我写了这个函数:

int internalPathLength(Node *t, int& sum) const{
        if(t == nullptr || (t->left == nullptr && t->right == nullptr)) {
            return 0;
        }
        else {
            int a = 0;
            sum += internalPathLength(t->left, sum) + internalPathLength(t->right, sum) + (countNodes(t,a)-1);
            cout << sum << endl;
            return sum;
        }

这个函数给了我一个565个节点的二叉搜索树,IPL为1,264,875,230,平均深度为2,238,717,这是一个非常高的数字。在类似大小的AVL树上使用它给我的IPL为-1,054,188,525,平均深度为-1,865,820,这是一个负数,而在高位之上。我对这种复发的解释/实施有什么不对吗?我还能尝试什么?或者毕竟是我在这个计算的正常范围内得到的值?

1 个答案:

答案 0 :(得分:2)

问题是您通过引用传递sum,因此它会增加太多次。你根本不需要这笔钱。这应该有效:

int internalPathLength(Node *t) const{
        if(t == nullptr || (t->left == nullptr && t->right == nullptr)) {
            return 0;
        }
        else {
            return internalPathLength(t->left) + internalPathLength(t->right) + countNodes(t) - 1;
        }
    }

这不是最佳选择,因为您的计数功能可能也是递归的。 您可以在同一递归中计算每个子树中的节点,然后使用它。像这样:

int internalPathLength(Node *t, int &count) const{
        if(t == nullptr) {
            count = 0;
            return 0;
        }
        else if(t->left == nullptr && t->right == nullptr){
            count = 1;
            return 0;
        }
        else {
            count = 1;
            int leftCount;
            int rightCount;
            int sum = internalPathLength(t->left, leftCount) + internalPathLength(t->right, rightCount);

            count += leftCount + rightCount;

            return sum + count - 1;
        }
    }