算法 - 如何在涉及if语句时计算时间复杂度

时间:2014-09-07 05:45:10

标签: algorithm

我是算法的新手,并且在if语句存在时如何计算时间复杂度有疑问。我有一个在堆中实现的优先级队列。这是出列方法:

int[] pQueue;
int length; 
int dequeue()
{
     int node = 1;
     int value = pQueue[--length];
     int maxValue = pQueue[node];

     int location = sift(node * 2, value);
     pQueue[location] = value;
     return maxValue;
}

int sift(int node, int value){
     if (node <= length){
         if (node < length && pQueue[node] < pQueue[node + 1])
         node++;
     if (value < pQueue[node]){
         pQueue[node / 2] = pQueue[node];
         return sift(node * 2, value);
         }
}
     return node / 2;
}

在sift方法中,有两行代码:

         if (node < length && pQueue[node] < pQueue[node + 1])
         node++;

由于n ++是根据上述条件执行的,在推导递推方程时我是否应该计算?我知道它确实会渐进地产生任何差异,但有没有任何标准的方法呢?非常感谢。

2 个答案:

答案 0 :(得分:2)

标准方法是在取决于所考虑的变量时考虑该条件。例如,考虑一个简单的递归函数,它在if语句中调用它自己:

double factorial(int n) {
    double result = n;
    if (n > 0) {
        result *= factorial(n - 1);
    }
    return result;
}

如果我们假装总是满足if - 条件,那么递归是无界的,复杂性是无限的(无论 n )。如果我们假装永远不会满足if - 条件,那么递归调用永远不会发生,并且复杂性是不变的。显然,这些都不是可以接受的假装;复杂性实际上是O( n )。

当条件依赖于所考虑的变量时,标准方法通常是给出最坏情况的复杂性(并指示我们这样做)。例如,对于排序算法,我们通常根据被排序的序列的长度给出复杂性,但是许多排序算法根据元素的初始排序执行不同。因此,我们假设我们对序列的性能感兴趣,并且 有利于它们的长度排序,并相应地进行计算。

(通常也可以提供平均情况复杂度,但是,通过平均所有可能的输入,有时甚至是典型案例复杂性。)

答案 1 :(得分:0)

找出最坏情况的上限。 sift()之前的每一行调用1次。除了递归调用之外,sift()内的所有指令都需要恒定的时间:

return sift(node * 2,value);

该特定行具有由n确定的最大递归调用量。具体地说,它将调用自身直到节点超过n-1(节点&lt; = length,回想起该长度减1)。请记住,每次递归调用时节点都会加倍。因此,节点加倍多次,直到它超过n,因此它调用lg(n)次。这代表了最糟糕的情况,其中value是pQueue堆子树中最少的元素。现在,到了你的观点。

由于递归调用常数Θ(1)指令O(lg(n))次,你真的不应该关注递归方程中的常数,因为所有这些都在Θ(1)下总和:

T(n)= O(lg(n))+Θ(1)