将值从叶传递到根

时间:2018-03-13 00:15:34

标签: c++ tree tree-traversal

我已经解决了很多与树相关的问题,但是,我仍然对树的一个特定方面(一般的递归)没有信心:

  

如何将值从叶传播到根?

例如,考虑我们有一个二叉树,其中我们必须找到具有最小总和的根到叶子路径。对于树图像here,总和将为7(对应于两条路径0-3-2-1-1或0-6-1)。

我写了以下代码:

struct Node
{
  int cost;
  vector<Node *> children;
  Node *parent;
};

int getCheapestCost( Node *rootNode )
{
  if(!rootNode) return 0;

  return dfs(rootNode, INT_MAX, 0);
}

int dfs(Node* rootNode, int minVal, int currVal) {
  if(!rootNode) return;

  currVal+=rootNode->cost;
  if(rootNode->children.empty()) {
    minVal = min(minVal, currVal);
    return minVal;
  }

  for(auto& neighbor: rootNode->children) {
    dfs(neighbor, minVal, currVal);
  }

  return currVal;    //this is incorrect, but what should I return?
}

我知道最后一个return currVal是不正确的 - 但那我该怎么回事?从技术上讲,我只想在到达叶节点时返回minVal的值(当我在中间节点时没有值)。那么,如何将minVal从叶节点传播到最顶层的root节点?

P.S。:我正在准备面试,这对我来说是一个很大的痛苦领域,因为我几乎每次都被困在这一点上。我非常感谢任何帮助。感谢。

编辑:对于这个特定的一个,我不知何故wrote a solution使用传递引用。

1 个答案:

答案 0 :(得分:1)

for 中保存所有孩子的 minVal 并返回minVal而不是currVal。

for(auto& neighbor: rootNode->children) {
  minVal = min(minVal, dfs(neighbor, minVal, currVal));
}
return minVal;

这样你总是会返回minVal,通过递归一直到第一次调用。

修改:说明

我将使用您在问题中提供的tree作为示例。我们首先在根(0)处输入树。它会向currVal添加0,不会输入第一个if,然后输入for。一旦它出现,将从第一个孩子再次调用该函数。

在第一个节点(5),它将添加该值,检查它是否为结束,然后转到下一个节点(4),再次添加,currVal现在为9.然后,因为(4)没有孩子们,它会返回 min(currVal,minVal)。此时,minVal为INT_MAX,因此返回9.

一旦返回这个值,我们回到调用它的函数,它在节点(5),恰好在我们调用(4)时,我们(我的修改)比较哪个值它与minVal一起返回。

min(minVal, dfs(neighbor, minVal, currVal))

此时,重要的是要注意当前的minVal仍然是INT_MAX,因为它不是引用,这是传递给函数的值。结果,我们现在将其设置为9。

如果(5)有其他孩子,我们现在将输入 dfs 的新实例,在我们得到结果时,将该值与9进行比较,但由于我们没有,我们结束 for 循环并返回 minVal ,返回根节点(0)。

从那里,我相信你可以猜到会发生什么,我们进入节点(3),分支到(2) - &gt;(1) - &gt;(1)和(0) - &gt;(10),返回分别为 for 循环的7和13,节点(6)最终也会返回7到(0)的 for 循环。

最后,(0)首先将INT_MAX与9进行比较,然后再与7进行比较,最后再与7进行比较,将7返回到 getCheapestCost

简而言之:

您的代码将继续输入 dfs ,直到找到没有子节点的节点,一旦发生这种情况,它将返回从该节点获取的 minVal ,然后返回调用它的函数,即父节点。

进入父节点后,您需要检查哪些子项提供了最小 minVal ,方法是将其与之前的 minVal (来自其他子级,分支机构或INT_MAX)进行比较。检查完所有子项后, minValue 将返回到下一个父项,后者将与其子项进行比较,直到它到达根节点。