对计数排序算法的复杂性感到困惑

时间:2016-02-04 17:05:02

标签: c counting-sort

我对计数排序算法有两个疑问:

  1. 复杂度如何O(n)?算法中有5个for循环。每个for循环的复杂性应该是n吗?导致n^4复杂性?我知道我错了,计算排序是线性的,但我想知道为什么我的推理是错误的。

  2. 如果计数排序算法是线性的,为什么它是O(n+K)而不仅仅是O(n),如果添加K,它就不再是线性的了吗?

  3. 这也是我所指的计数排序代码:

    void countSort(char *str)
    {
        // The output character array that will have sorted str
        char output[strlen(str)];
    
        // Create a count array to store count of inidividul characters and
        // initialize count array as 0
        int count[RANGE + 1], i;
        memset(count, 0, sizeof(count));
    
        // Store count of each character
        for(i = 0; str[i]; ++i)
            ++count[str[i]];
    
        // Change count[i] so that count[i] now contains actual position of
        // this character in output array
        for (i = 1; i <= RANGE; ++i)
            count[i] += count[i-1];
    
        // Build the output character array
        for (i = 0; str[i]; ++i)
        {
            output[count[str[i]]-1] = str[i];
            --count[str[i]];
        }
    
        // Copy the output array to str, so that str now
        // contains sorted characters
        for (i = 0; str[i]; ++i)
            str[i] = output[i];
    }
    

2 个答案:

答案 0 :(得分:2)

回答1:

有三个&#39; for&#39;每个都在O(n)中工作的循环 因此整体复杂性为:

O(n)+O(n)+O(n) = O(n+n+n) = O(3n)

3n的情况下,3是常量,可以忽略,因此复杂性会降低到O(n)

回答2:

算法不仅取决于数组的大小N,还取决于其中收集的数字的范围K。它需要一个更大的计数数组,因此需要迭代来对数组进行排序:

{1,10000000,3,2,0} // K=10000001

比它:

{1,4,5,2,3} // K=6

因此for循环使用代码的复杂性以这种方式计算:

for(i = 0; str[i]; ++i) // O(n)

for (i = 1; i <= RANGE; ++i) // O(k)

for (i = 0; str[i]; ++i) // O(n)

for (i = 0; str[i]; ++i) // O(n)

并且整体复杂性是O(n)+O(n)+O(n)+O(k) = O(n+k)的复杂性,并确定了我对您的问题的答案:算法复杂性仍被视为线性。

答案 1 :(得分:1)

渐近复杂度在某种意义上表示作为输入大小函数的操作数。这很有用,因为它显示了随着输入大小的增加算法减慢了多少。常数不会影响减速,因此会被忽略。忽略我们得到的常数:

strlen(str)执行strlen(str)次操作(它检查整个字符串,直到找到'\0'
memset()执行strlen(str)次操作 第二个for执行RANGE次操作 其他三个for中的每一个都执行strlen(str)次操作

在您的示例中,strlen(str)n表示,RANGEK表示。所以整个函数执行O(5n + K) = O(n + K)次操作。

n + K仍然是一个线性函数,可以是两个变量(它是一个幂1的多项式)。

为了更深入地理解这一点,你需要阅读更多关于渐近复杂性(严格的数学理论)的内容。