【问题标题】:Inorder Traversal || Call Stack space to be considered (or) Not?中序遍历 ||调用堆栈空间要考虑(或)不是?
【发布时间】:2019-11-12 19:23:55
【问题描述】:

这个问题已经在我脑海中萦绕了很多天,我希望有人能解决它。 问题:- 查找二叉树中的节点数

方法 1:-迭代) 使用堆栈进行中序遍历。每当您从堆栈中弹出元素时,请记下它的计数,即二叉树中的节点数。

时间复杂度 - O(n)

空间复杂度 - O(n)

方法 2:-递归

时间复杂度 - O(n)

空间复杂度 - O(1) 或 O(n)????

我们可以递归地进行中序遍历,但是在面试中,哪种方法最适合向面试官表达......迭代还是递归?我应该考虑递归调用堆栈空间,它将空间复杂度归结为 O(n) 还是应该坚持 O(1) 空间复杂度?

【问题讨论】:

  • 是的,在考虑空间复杂度时应该计算调用堆栈。请注意,两种算法的空间复杂度都是 O(h),其中 h 是树的高度;不是 O(n),其中 n 是节点数。
  • @kaya3 那么在这种情况下,为了找到节点的数量,堆栈方法也可以吗???

标签: data-structures tree tree-traversal space-complexity inorder


【解决方案1】:

您的问题 - “哪种方法最适合向面试官表达” - 除了面试官自己之外,任何人都无法真正回答。但是,解决这个问题的可能方法之间的差异值得讨论。


首先,让我们注意迭代和递归方法都使用堆栈;迭代方法具有显式堆栈,但递归函数使用不由程序员管理的call stack 工作。因此,两种方法使用的辅助空间将渐近相同,但迭代方法的常数较低,因为它只将节点推送到堆栈,而递归方法推送整个调用帧,包括所有局部变量。

注意辅助空间是 O(h) 其中 h 是树的高度,而不是 O(n) 其中 n 是节点数。这很重要,因为最坏的情况取决于树是否为balanced。对于不平衡树,高度h在最坏情况下为O(n),而对于平衡树,h为O(log n)。该问题没有指定树是平衡的,因此当树的高度太大时,递归方法存在overflow the stack 的风险。相比之下,迭代方法将显式堆栈存储在主内存中。


以上都是关于效率的讨论,但编程的效率远不止算法效率。例如,如果树永远不会很大,您可能更喜欢递归方法,因为它更容易编写;它只需要几行非常干净的代码。命令式方法需要创建一个堆栈,并在循环中从堆栈中推送和弹出,因此代码可能会更长且更难理解。不要低估干净、易于理解的代码的价值。


另一件事是你已经直接跳到按顺序遍历作为问题的解决方案,但是如果问题是计算二叉树中的节点数,那么你可以按任何顺序遍历它。前序遍历比中序遍历更易于迭代实现,并且同样高效。

另外,如果数据结构本身可以修改,那么直接给每个节点一个属性来保存其子树的基数。插入、删除和重新平衡操作将需要修改以保持此属性,但额外的工作是 O(1),它允许通过简单地读取根节点的基数在 O(1) 内计算树的大小财产。添加此属性还有其他好处,例如支持在 O(h) 时间而不是 O(h) 时间内“找到第 k 个节点”操作> + k).

【讨论】:

  • 哇...这是一些明确的解释...非常感谢您抽出宝贵时间并清楚地解释它。
猜你喜欢
  • 2016-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-12
  • 2011-12-22
  • 1970-01-01
相关资源
最近更新 更多