如何在二叉树中找到给定深度的节点值的总和?

时间:2010-06-11 03:47:27

标签: search tree traversal

为此我一直在摸不着头几个小时......

问题:

Binary Tree

   (0)      depth 0
   / \
  10   20   depth 1
 / \   / \
30 40  50 60  depth 2

我正在尝试编写一个以深度为参数的函数,并返回给定深度的节点值的总和。

例如,如果我通过2,它应该返回180(即30 + 40 + 50 + 60)

我决定使用呼吸优先搜索,当我找到具有所需深度的节点时, 总结价值,但我无法弄清楚如何找出哪个节点处于什么深度的方式。 但是通过这种方法,我觉得完全错误的方向。

function level_order($root, $targetDepth) {
$q = new Queue();
$q->enqueue($root);

while(!$q->isEmpty) {
    //how to determin the depth of the node???
    $node = $q->dequeue();

    if($currentDepth == $targetDepth) {
        $sum = $node->value;
    }

    if($node->left != null) {
        $q->enqueue($node->left);
    }
    if($node->right != null) {
        $q->enqueue($node->right);
    }
    //need to reset this somehow
    $currentDepth ++;
}

}

8 个答案:

答案 0 :(得分:9)

只需递归进行深度优先搜索,保持当前级别并将给定深度的节点求和。

伪代码:

sum(Node, Level) = 
  if (Level == 0) return Node.value;
  else return f(Node.left, Level-1) + 
              f(Node.right, Level-1).

答案 1 :(得分:2)

使用recursion很容易:

int calc_sum(node, depth)
{
  if (depth > 0)
  {
    sum = 0   
    for every children n of node
      sum += calc_sum(n, depth -1)
    return sum
  }
  else
    return node.value
}

这将计算树d的深度t处的部分和,作为t.children在深度d-1处的值的总和。就像你想知道你将剩余的深度与你计算的子树一起作为参数。

如果您想要更高效的解决方案,可以使用动态编程以迭代方式解决此问题。

答案 2 :(得分:2)

您实际上可以避免递归,仍然使用广度优先搜索。这样做的方法是保持每个节点的级别(深度)。最初,您只需将根级别设置为0.现在,在执行BFS时,当您从节点u移动到节点v时,可以设置depth[v] = depth[u] + 1。要保持深度,您可以使用常规数组,也可以在BFS队列中添加另一个额外元素。这是一个函数的伪代码,它在具有d个节点的二叉树中查找深度为n的节点值的总和,其中我在队列中添加了另一个元素来表示深度:

int findSum(d) { 

    ans = 0;
    q = new Queue(); //define the queue
    q.push(root, 0); //insert the root, which has depth 0.

    while(! q.empty()) {
        current_node = q.top().first, current_depth = q.top().second; //Get the current node and its depth
        q.pop(); //remove the current node from the queue

        if(current_depth == d)
            ans += current_node -> value; //if the current node is on the required depth, then add its value to the answer

        if(current_node -> left != NULL)
            q.push(current_node -> left, current_depth + 1); //add the left child to the queue, which has a depth of one more than the current depth

        if(current_node -> right != NULL)
            q.push(current_node -> right, current_depth + 1); //add the right child to the queue, which has a depth of one more than the current depth
    }
    return ans;
}

答案 3 :(得分:1)

int sumOnSelectedLevel(BNode node, int k){
            if(k==0) return node.data;
            int left = node.left == null? 0: sumOnSelectedLevel(node.left, k-1);
            int right = node.right == null? 0: sumOnSelectedLevel(node.right, k-1);
            return left+right;
        }

还处理NullPionterException。

答案 4 :(得分:0)

int sum(Node node , int Level)

`{ if(level==depth)
        return Level;
    else
    return ( sum(node.left, Level+1), sum(node.right, Level+1)`}

答案 5 :(得分:0)

以下是我必须为面试问题实施的类似内容。希望这会有所帮助。

//Can you write me a function that returns an array of all the averages of the nodes 
//at each level (or depth)??


BinarySearchTree.prototype.nodeAverages = function() {
    var node = this.root;
    var result = {};
    var depthAverages = [];

    var traverse = function(node, depth) {
        if (!node) return null;
        if (node) {
            if (!result[depth])
                result[depth] = [node.value];
            else
                result[depth].push(node.value);
        }
        //check to see if node is a leaf, depth stays the same if it is
        //otherwise increment depth for possible right and left nodes
        if (node.right || node.left) {
            traverse(node.left, depth + 1);
            traverse(node.right, depth + 1);
        }
    };
    traverse(node, 0);

    //get averages and breadthFirst
    for (var key in result) {
        var len = result[key].length;
        var depthAvg = 0;
        for (var i = 0; i < len; i++) {
            depthAvg += result[key][i];
        }
        depthAverages.push(Number((depthAvg / len).toFixed(2)));
    }
    return depthAverages;
};

//Tests
var bst = new BinarySearchTree();
bst.add(10).add(20).add(30).add(5).add(8).add(3).add(9).add(7).add(50).add(80).add(98);
console.log(bst.nodeAverages()); //[ 10, 12.5, 13.67, 22, 80, 98 ]

答案 6 :(得分:0)

    public static void LevelSum(Node root, int level)
    {
        Queue<Node> q = new Queue<Node>();
        q.Enqueue(root);
        --level;

        while (true)
        {
            int count = q.Count;
            while (count > 0 && level > 0)
            {
                var temp = q.Dequeue();
                if (temp.Left != null)
                    q.Enqueue(temp.Left);
                if (temp.Right != null)
                    q.Enqueue(temp.Right);
                count--;
            }
            if (level == 0)
            {
                count = q.Count;
                var sum = 0;
                while (count > 0)
                {
                    sum += q.Dequeue().data;
                    count--;
                }
                Console.WriteLine(sum);
                return;
            }
            else if (level > 0)
                level--;
            else
                return;
        }
    }

答案 7 :(得分:0)

简单的递归算法。调用方法时,当前级别始终为0。

public int SumSameLevelNodes(int levelToFind, int currentLevel)
    {
        if (this == null)
            return 0;
        int sum = 0;
        if (currentLevel == levelToFind)
            sum = this.value;
        if (this.lNode != null && currentLevel < levelToFind)
        {
            sum += lNode.SumSameLevelNodes(levelToFind, currentLevel + 1);
        }
        if (this.rNode != null && currentLevel < levelToFind)
        {
            sum += rNode.SumSameLevelNodes(levelToFind, currentLevel + 1);
        }
        return sum;
    }