问题
I've been scratching my head for several hours for this...
problem:
Binary Tree
(0) depth 0
/ \
10 20 depth 1
/ \ / \
30 40 50 60 depth 2
I am trying to write a function that takes depth as argument and return the sum of values of nodes of the given depth.
For instance, if I pass 2, it should return 180 (i.e. 30+40+50+60)
I decided to use breath first search and when I find the node with desired depth, sum up the value, but I just can't figure out how to find out the way which node is in what depth. But with this approach I feel like going to totally wrong direction.
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 ++;
}
}
回答1:
Just do a depth-first search recursively, keep the current level and sum the nodes at given depth.
The pseudocode:
sum(Node, Level) =
if (Level == 0) return Node.value;
else return f(Node.left, Level-1) +
f(Node.right, Level-1).
回答2:
With recursion it will be easy:
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
}
this will compute the partial sum at depth d
of a tree t
as the sum of values of t.children
at depth d-1
. Like you were wondering you bring the remaining depth together with the subtree you are calculating as a parameter.
If you want a more efficient solution you can use dynamic programming to resolve this problem in an iterative way.
回答3:
You can actually avoid recursion, and still use a Breadth-First Search. The way to do that, is keeping the level (depth) of each node. Initially, you just set the root's level to be 0. Now, while doing the BFS, when you move from a node u
to a node v
, you set depth[v] = depth[u] + 1
. To keep the depth, you either use a regular array, or add use another extra element in the BFS queue. Here is pseudocode of a function that finds the sum of values of nodes at depth d
in a binary tree with n
nodes, where I added another element to the queue to represent the depth:
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;
}
回答4:
int sum(Node node , int Level)
`{ if(level==depth)
return Level;
else
return ( sum(node.left, Level+1), sum(node.right, Level+1)`}
回答5:
Here is something similar that I had to implement for an interview question. Hopefully this helps.
//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:
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:
Simple recursive algorithm. The current level yields always 0 when calling method.
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;
}
来源:https://stackoverflow.com/questions/3020070/how-to-find-sum-of-nodes-value-for-given-depth-in-binary-tree