BST:将每个键值增加所有其他更大键的总和

时间:2014-11-29 17:08:00

标签: java

问题陈述:给定二进制搜索树(BST),将其转换为二叉树,使原始BST的每个密钥都更改为密钥加上BST中所有更大密钥的总和。

Input:  BST
              5
            /   \
           2     13
                /  \
               11  14

Output: The given BST is converted to following Binary Tree

              43
             /  \
            45   27
                /  \
               38   14

我能够在网上挖出这段有用的代码,但我无法理解它。到目前为止,传递一个变量来维持前一个总和使我的理解变得更加复杂。

请注意用更好的代码解释解释。或者使下面的代码更直观。

public class BSTWithInts
{
    private Node root;

    private class Node
    {
        Node leftChild;
        Integer item;
        Node rightChild;
    }

    public void addsNodes()
    {
        addSumUtil(root, 0);
    }


    private int addSumUtil(Node node, int sum)
    {
        if(node == null)
            return 0;

        if ( node.rightChild != null )
        {
            sum = addSumUtil(node.rightChild, sum);
        }
        if ( node.leftChild != null )   
        {
            sum = addSumUtil(node.leftChild, sum);

            // why are we doing this here, shouldn't we just 
            // traverse right tree only first
        }

       node.item += sum;
       sum = node.item;
       return sum;
    }
}
编辑:我刚刚意识到代码的运行方式不正常。

              5             
            /   \
           2     13

    should give 

             18
            /   \
          20     13

    and not      
             20
            /   \
          15    13

2 个答案:

答案 0 :(得分:1)

要了解上述代码中的内容,您需要了解递归的工作原理。

开始理解这个问题的简单方法是在处理过程中使用System.out.println语句,让左右儿童更好地了解正在发生的事情:

        if ( node.rightChild != null )
        {
            System.out.println("Accessing right child: "+node.rightChild.item);
            sum = addSumUtil(node.rightChild, sum);
        }
        if ( node.leftChild != null )   
        {
            System.out.println("Accessing left child: "+node.leftChild.item);
            sum = addSumUtil(node.leftChild, sum);

            // why are we doing this here, shouldn't we just 
            // traverse right tree only first
        }

您将发现print语句的输出按以下顺序排列,从而确认每个节点的正确子节点在其左子节点之前被计算。

Accessing right child: 13
Accessing right child: 14
Accessing left child: 11
Accessing left child: 2

答案 1 :(得分:1)

想象一下你做这件事最简单的方法,记住它是一个搜索树,所以一切都井然有序。你想要从最高的数字开始。记录下来,不管它。然后是第二高的数字:为它添加最高数字,并保留一份副本,因为这也是"所有数字的总和高于第3个最高数字"。将其添加到第3个最高数字并保留总和,因为它将被添加到第4个最高数字。你拖动它的总和,每次增加当前数字(反之亦然)。当你得到最小的数字时,你已经得到了树的其余部分的总和,准备添加它。

另外,我认为您找到的代码是错误的,即使它在示例树上有效。它看起来应该更像:

private int addSumUtil(Node node, int sum)
{
    if (node == null) {
        return sum;
    }

    sum = addSumUtil(node.rightChild, sum);
    sum = node.item += sum;
    sum = addSumUtil(node.leftChild, sum);

    return sum;
}

请注意,sum = addSumUtil(null, sum);是noop。