这个递归算法的大O.

时间:2010-02-20 15:12:45

标签: algorithm heap big-o tree-traversal

我做了以下涉及二元堆结构的算法:

Algorithm: heapMinimum(node)
Input    : Position n
Output   : Sequence minList; containing the postions that hold the minimum value

1. minList <-- sequence
2. if parent(node) == NULL // current node is the root of the tree
3.   minList.insertLast(node)
4. if (leftchild(node).element() == node.element())
5.   concat(heapMinimum(leftchild(node), minList))
6. if(right(node).element() == node.element())
7.   concat(heapMinimum(rightChild(node), minList))
8. return minList

算法的作用基本上是遍历二进制堆,给定其根,以查找并存储保持最小值的节点(即与根的值匹配的值)。

现在我无法用Big O表示法计算算法的运行时间。我感到困惑的原因是因为用于遍历每个节点的左右子节点的递归。

O(1)外,所有操作都在concat的固定时间内运行。但是,如何计算这种递归解决方案的运行时间呢?

4 个答案:

答案 0 :(得分:4)

对我来说看起来像O(N),其中N是元素的数量。如果您的堆只包含相同的元素,则将遍历所有元素。另外,为什么不是concat O(1)?只要你“连接”数字,它也应该是O(1)。如果以某种方式c​​oncat是O(N)(从你的伪代码看起来它是 - 但你应该重新考虑,如果你真的需要连接两个返回的列表),那么总时间将是O(N 2 )最坏的情况。

答案 1 :(得分:1)

我假设你在谈论二进制堆?

通过定义堆属性,您应该只进行递归,直到找到大于根的元素为止。但是,您还必须确保树的当前级别的其他元素都不与根相同。从本质上讲,这会产生这样的规则:一旦遇到堆的元素大于根,您就不需要递归到元素的子元素中。

但是,在最坏的情况下,每个元素可能等于根。在这种情况下,您必须检查整个堆,这会产生O(n)时间,其中n是堆中元素的数量。

所以回答你的问题,是O(n)

答案 2 :(得分:0)

正如其他人所提到的,如果你的concat()是O(1)[如果不是,你就可以这样做]那么你的算法就是输出大小的O(N)。

但是,如果您使用了复制列表的concat()(取决于系统,这很容易意外),那么最坏的情况是输出大小为O(N ^ 2)。导致此行为的一种情况是,当您的最小节点深入到树中时,您的concat()会不断复制每个级别的列表。

请注意,此深度受堆深度的限制,因此如果树是平衡的,则最坏的情况也是数据结构大小为O(M log M)。您可以看到这一点,因为最大副本数是树的深度。

答案 3 :(得分:0)

我想您的解决方案中存在错误。 第一次检查:

  

如果parent(node)== NULL

必须删除

,但必须添加 node!= NULL 的检查。

此外,我建议使用list作为附加参数,您将在其中提供答案。 那么,这就是我的实施:

Algorithm: heapMinimum(node, minList)
if (node != NULL)
{
   if (minList.empty() || minList.getFirst().element() == node.element())
   {
      minList.insertLast(node)

      heapMinimum(left(node),  minList)
      heapMinimum(right(node), minList)
   }
}

假设在列表中添加一个元素取O(1),我们得到该函数需要O(k),其中k是堆中最小值的数量。

享受。