是否有一种排序算法可以在O(n)时间内将n个不同的整数从3到4n排序?
我一直在尝试这个问题一个小时,我不知道该怎么做。
任何提示?
答案 0 :(得分:10)
首先,基于比较的排序算法不能比O(nlogn)的最坏情况时间复杂度更好,所以不要使用它们中的任何一个。
因为它是家庭作业,请看:
希望这有帮助。
答案 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
以下是它的工作原理:
它创建一个布尔数组来指示是否找到了一个数字,最初将所有条目设置为false。这是一个O(n)操作,因为此数组的限制为3
到4n
。你可以使用布尔值,因为数字是不同的。
然后,对于列表中的每个数字,它将相关的布尔值设置为true以表明它在列表中 - 这也是O(n),因为您正在处理n
条目。 / p>
然后,它按顺序重新填充数组,O(n)与上述第(1)点相同的原因。
当然,它需要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]
中。
接下来考虑两个数字a
和b
,a < 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);
}
答案 7 :(得分:-3)
线程排序!
将数组的每个项目发送到一个单独的线程中,告诉线程休眠几个毫秒,等于整数值的平方,因为线程唤醒时让它们将项目添加到数组中。