排序算法,将在O(n)时间内排序n个不同的整数

时间:2011-11-08 04:30:40

标签: algorithm sorting big-o

是否有一种排序算法可以在O(n)时间内将n个不同的整数从3到4n排序?

我一直在尝试这个问题一个小时,我不知道该怎么做。

任何提示?

8 个答案:

答案 0 :(得分:10)

首先,基于比较的排序算法不能比O(nlogn)的最坏情况时间复杂度更好,所以不要使用它们中的任何一个。

因为它是家庭作业,请看:

  1. Counting sort
  2. Bucket Sort
  3. Radix Sort
  4. 希望这有帮助。

答案 1 :(得分:2)

是的,与大多数优化一样,您可以根据以下伪代码交换空间:

def sortNums (nums[]):
    # Create 'isThere' array indicating if you're found the number.

    var isThere[3..(4*nums.count)] of boolean
    for i in 3..(4*nums.count):
        isThere[i] = false

    # Process each number in list, setting relevant 'isThere' entry to true.

    for each num in nums:
        isThere[num] = true

    # Process 'isThere' array to repopulate the number array in sorted fashion.
    pos = 0
    for i in 3..(4*nums.count):
        if isThere[i]:
            nums[pos] = i
            pos = pos + 1

以下是它的工作原理:

  1. 它创建一个布尔数组来指示是否找到了一个数字,最初将所有条目设置为false。这是一个O(n)操作,因为此数组的限制为34n。你可以使用布尔值,因为数字是不同的。

  2. 然后,对于列表中的每个数字,它将相关的布尔值设置为true以表明它在列表中 - 这也是O(n),因为您正在处理n条目。 / p>

  3. 然后,它按顺序重新填充数组,O(n)与上述第(1)点相同的原因。

  4. 当然,它需要O(n)空间,而其他一些类型可能能够就地运行,但是,因为你没有对此进行限制(并且你的问题已明确将范围限制在它是可行的(a)),我假设没关系。


    (a)如果没有限制范围,很可能可行,原因很简单,因为所需空间可能很大。

答案 2 :(得分:0)

我创建了一个名为“shift sort”的算法,该算法在给定一些约束的情况下在O(n)中运行。它可以在http://sumofchoices.com/projects/sort.php

找到

如果您想要更传统的算法,请使用存储桶,基数或计数算法。

答案 3 :(得分:0)

由于您的范围是[3, 4*N],您可以将所有数字记录在二维数组aux[N][4]中 - 数字的低两位(即提示模4)确定列和高位(整数部分)确定行。

所以你要做的第一个是零辅助数组,然后在原始数组上进行一次传递,将每个数字存储在aux[a[i] div 4][a[i] mod 4]中。

接下来考虑两个数字aba < b。你有两种情况:

1)a div 4 == b div 4;它跟随a mod 4 < b mod 4,因此数字将位于aux的同一行,但a将位于编号较低的列中。< / p>

2)a div 4 < b div 4;因此a将位于编号较低的行中。

因此,以行主顺序遍历辅助数组并取非零值将为您提供排序序列。

#include <stdio.h>
#include <string.h>

#define N 16 /* Range 3 - 4*N */

int a [] = { 5, 8, 11, 27, 18, 33, 3, 7, 10, 22, 64 };

#define M (sizeof a / sizeof a[0])

int aux[N][4];

void
sort  ()
{
  int i, j;

  memset (aux, 0, sizeof aux);

  for (i = 0; i < M; ++i)
    aux [a [i] >> 2][a [i] & 3] = a [i];

  j = 0;
  for (i = 0; i < N; ++i)
    {
      if (aux [i][0])
        a [j++] = aux [i][0];
      if (aux [i][1])
        a [j++] = aux [i][1];
      if (aux [i][2])
        a [j++] = aux [i][2];
      if (aux [i][3])
        a [j++] = aux [i][3];
    }
}


int
main ()
{
  int i;

  sort();
  for (i = 0; i < M; ++i)
    printf ("%d ", a [i]);
  puts ("");
  return 0;
}

编辑:但我更喜欢paxdiablo的解决方案

答案 4 :(得分:0)

但是是否可以给出a[1....n]的数组n bit integers,并在O(n)时间对它们进行排序。

答案 5 :(得分:0)

http://www.cs.rutgers.edu/~muthu/soradix.pdf

基本上,该过程是桶排序,其中列表的辅助数据 与每个桶相关联(即,列表中的元素之间的链接)被实现 通过P中的伪指针而不是将其显式存储在位存储器中 (缺乏单词级并行性,访问效率低下)。值得的 注意到用伪指针实现的桶列表是分散的 一个大于我们用显式指针获得的区域(那个 是因为每个伪指针都有一个log n位的键,而一个显式指针 只有log d位)。

答案 6 :(得分:0)

线性化珠子排序在O(kN)时间和O(2N)空间中运行,其中k是要排序的最大值。

void sort(int A[], int N) {
    int i,count;
    int *R = calloc(N,sizeof(int));
    do {
       count=0;
       for (i=0;i<N;i++) { if (A[i]) { count++;  A[i]--;} }
       for (i=0;i<count;i++) { R[i]++; }
    } while(count);
    memcpy(A,R,N*sizeof(int));  //A is now sorted descending.
    free(R);
 }

请参阅What is this O(N*k) sorting algorithm?

答案 7 :(得分:-3)

线程排序!

将数组的每个项目发送到一个单独的线程中,告诉线程休眠几个毫秒,等于整数值的平方,因为线程唤醒时让它们将项目添加到数组中。