如何在线性时间内排序二进制数组?

时间:2017-02-12 13:48:10

标签: arrays algorithm sorting binary time-complexity

http://www.techiedelight.com/sort-binary-array-linear-time/

线性时间意味着我们只需要遍历数组一次但是根据这里的解决方案,我们将首先遍历数组以找到零的数量,然后我们再次遍历它以填充数组的第一部分用零和剩下的部分用。

那么,线性时间解决方案怎么样? 我错过了什么?

6 个答案:

答案 0 :(得分:3)

时间复杂度线性时间表示为O(n)。这意味着运行时间相对于输入的大小线性增加。这个数组的所有元素的总和的例子,与数组的长度成比例。

具体到您的示例,请查看Sort()中的此循环:

int zeros = 0;
for (int i = 0; i < n; i++)
    if (A[i] == 0)
        zeros++;

此循环线性遍历A[],并对零的数量求和。线性时间也适用于这些循环:

int k = 0;
while (zeros--)
    A[k++] = 0;

// fill all remaining elements by 1
while (k < n)
    A[k++] = 1;

因为您只是遍历A[]一次。

这些操作组合为O(2n),因为数组遍历了两次。因此,函数Sort()O(2 * n)操作,相当于O(n)

这是另一个例子。如果你需要排序100个二进制数字与10个二进制数字相比,这需要更多的时间?在这种情况下,排序100个二进制数将比排序10个二进制数长10倍。这是因为线性时间相对于输入n的大小增加线性

答案 1 :(得分:2)

如果算法的时间复杂度为O(n),则称算法采用线性时间或O(n)时间。非正式地,这意味着对于足够大的输入大小,运行时间随输入的大小线性增加。

因为这个alogorithm横穿阵列两次。它仍然是线性的。想象一个线性方程y = 2 * x。

答案 2 :(得分:1)

所有共享的方法都是线性时间复杂度,即O(n)。但是直接/直接地他们在数组中遍历相同的元素两次并且Aquarius(The Asker)正在寻找一次性遍历方法。下面的代码遍历数组一次并在遍历时对其进行排序。

int left = 0, right = arr.length - 1;
while (left < right)
    {
        while (arr[left] == 0 && left < right)
            left++;

        while (arr[right] == 1 && left < right)
            right--;

        if (left < right)
        {
            arr[left] = 0;
            arr[right] = 1;
            left++;
            right--;
        }
    }

记录,

  

O(c * n)= O(n),其中c是常数

答案 3 :(得分:0)

在解决方案中,遍历数组两次。因此,订单为O(2n) = O(n)。 Big-O表示法忽略常量。 n2n都与n的值呈线性增长。将常数乘以或添加到函数不会改变函数的行为。

答案 4 :(得分:0)

&#34;线性时间&#34;意味着算法需要的时间随阵列的大小线性增加。在这里,对于添加到数组中的每个项目,您还有两个比较(即2n)。

答案 5 :(得分:0)

O(2n),O(1221n),O(n),O(n / 2)。所有这些都是线性的。这意味着执行的时间总是不断变化。因此,如果你有大小为10的数组,它总是需要比排序大小为5的数组多两倍的时间。