通过快速排序方法查找分区的时间复杂度

时间:2013-09-21 14:04:56

标签: algorithm analysis

这是一个使用Quicksort分区算法在n个元素数组中找到第k个最小数的算法。

    small(a,i,j,k)
     {
      if(i==j) return(a[i]);
      else
      {
      m=partition(a,i,j);
      if(m==k) return(a[m]);
      else
        {
         if(m>k) small(a,i,m-1,k);
         else small(a,m+1,j,k);
        }     
       }
     }

其中i,j是数组的起始和结束索引(j-i = n(数组中元素的数量)),k是最小的第k个,无法找到。 我想知道什么是最好的情况,以及上述算法的平均情况以及简要说明。我知道我们不应该在最好的情况下计算终止条件,并且分区算法也需要O(n)。我不希望渐近符号,但如果可能的话,我想要精确的数学结果。

1 个答案:

答案 0 :(得分:2)

首先,我假设数组已经排序 - 你没有提到 - 因为该代码不会起作用。而且,这对我来说就像常规的二元搜索一样。

总之...

最好的情况是当数组是一个元素长(你因为i == j而立即返回),或者对于大的n值,如果中间位置m与k相同;在这种情况下,不会进行递归调用,也会立即返回。这最好是O(1)。

对于一般情况,考虑T(n)表示使用算法解决大小为n的问题所花费的时间。我们知道:

T(1)= c

T(n)= T(n / 2)+ c

其中c是恒定时间操作(例如,如果i与j相同则比较时间等)。一般的想法是,为了解决大小为n的问题,我们消耗一些恒定时间c(以决定m == k,如果m> k,计算m等),然后我们消耗所花费的时间解决了一半大小的问题。

扩展重复可以帮助你推导出一个通用公式,虽然这很直观,这是O(log(n)):

T(n)= T(n / 2)+ c = T(n / 4)+ c + c = T(n / 8)+ c + c + c = ... = T(1)+ c * log(n)= c *(log(n)+ 1)

这应该是确切的数学结果。该算法在O(log(n))时间内运行。平均案例分析更难,因为您需要知道算法的使用条件。阵列的典型大小是多少? k的典型大小?数组中k的最小位置是什么?例如,如果它在中间,则平均情况可以是O(1)。这实际上取决于你如何使用它。