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

发布于 2024-12-14 08:23:47 字数 102 浏览 0 评论 0原文

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

我已经尝试这个问题一个小时了,但我不知道该怎么做。

有什么建议吗?

Is there a sorting algorithm that can sort n distinct integers from 3 to 4n in O(n) time?

I have been trying this problem for an hour now and I have no idea what to do.

Any tips?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

凉月流沐 2024-12-21 08:23:47

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

由于这是作业,请查看:

  1. 计数排序
  2. 桶排序
  3. 基数排序

希望这会有所帮助。

First of all, comparison based sorting algorithms cannot do better than a worst case time complexity of O(nlogn), so don't use any of them.

As it is homework, look at:

  1. Counting sort
  2. Bucket Sort
  3. Radix Sort

Hope this helps.

时光磨忆 2024-12-21 08:23:47

是的,与大多数优化一样,您可以用空间换取时间,如以下伪代码所示:

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) 相同。

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


(a)如果没有限制范围,它很可能无法工作,仅仅是因为所需的空间可能很大。

Yes, as with most optimisations, you can trade space for time, as per the following pseudo-code:

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

Here's how it works:

  1. It creates a boolean array to indicate whether a number has been found, initially setting all entries to false. This is an O(n) operation because the limit of this array is 3 through 4n. You can get away with using a boolean since the numbers are distinct.

  2. Then, for every number in the list, it sets the relevant boolean to true to state that it's in the list - this is again O(n) since you're processing n entries.

  3. Then, it repopulates the array in order, O(n) for the same reason the above point (1) is.

Of course, it requires O(n) space whereas some other sorts may be able to run in-place but, since you didn't place a restriction on that (and your question has explicitly limited the range to the point where it's workable(a)), I'm assuming that's okay.


(a) It would most likely not be workable without a restricted range, simply because the space required may be massive.

谎言 2024-12-21 08:23:47

我创建了一个称为“移位排序”的算法,在给定一些约束的情况下,该算法的运行时间复杂度为 O(n)。 可以在 http://sumofchoices.com/projects/sort.php 找到它

如果您愿意, 更传统的算法,使用桶、基数或计数算法。

I created an algorithm I called the "shift sort" which operates in O(n) given a few constraints. It can be found at http://sumofchoices.com/projects/sort.php

If you want a more traditional algorithm, use the bucket, radix, or counting algorithm.

醉生梦死 2024-12-21 08:23:47

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

因此,您要做的第一件事是将辅助数组清零,然后对原始数组进行一次传递,将每个数字存储在 aux[a[i] div 4][a[i] mod 4] 中。

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

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

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 的解决方案

Since your range is [3, 4*N] you can record all of your numbers in a two-dimensional array aux[N][4] - the lower two bits of the number (i.e. the reminder modulo 4) determines the column and the upper bits (the integral part) determine the row.

So the first you do is zero the auxiliary array then make one pass over the original array, storing each number in aux[a[i] div 4][a[i] mod 4].

Next consider two numbers a and b, a < b. You have two cases:

1) a div 4 == b div 4;it follows that a mod 4 < b mod 4 hence the numbers will be in the same row in aux, but a will be in a lower numbered column.

2) a div 4 < b div 4; it follows that a will be in a lower numbered row.

Therefore, traversing the auxiliary array in row-major order and taking non-zero values will give you a sorted sequence.

#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;
}

EDIT: But I like paxdiablo's solution more

深海不蓝 2024-12-21 08:23:47

但是是否可以给定一个 log n 位整数 的数组 a[1....n],并在 O(n)< 中对它们进行排序/代码> 时间。

But is it possible to given an array a[1....n] of log n bit integers, sort them in place in O(n) time.

篱下浅笙歌 2024-12-21 08:23:47

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

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

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

Basically, the procedure is bucket sorting where the auxiliary data of the list
associated to each bucket (i.e. the links among elements in the list) is implemented
by pseudo pointers in P instead of storing it explicitly in the bit memory
(which lacks of word-level parallelism and is inefficient in access). It is worth
noting that the buckets’ lists implemented with pseudo pointers are spread over
an area that is larger than the one we would obtain with explicit pointers (that
is because each pseudo pointer has a key of log n bits while an explicit pointer
would have only log d bits).

挽心 2024-12-21 08:23:47

线性化珠排序在 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);
 }

请参阅这个 O(N*k) 排序算法是什么?

A linearized bead sort runs in O(kN) time and O(2N) space, where k is the maximum value to be sorted.

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);
 }

See What is this O(N*k) sorting algorithm?

感受沵的脚步 2024-12-21 08:23:47

线程排序!

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

Thread sort!

Send each item of the array in a separate thread, tell the thread to sleep for a number of milliseconds equal to the square of the integer value, as the threads wake up have them add their item to an array.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文