【问题标题】:Sorting algorithm for list of integers整数列表的排序算法
【发布时间】:2012-01-24 06:37:31
【问题描述】:

我有一个大约 200 个整数的列表,它们的值在 1 到 5 之间。

我想学习排序算法并知道在哪里应用每种算法,因为目前我对所有被告知的事情都使用冒泡排序是一种糟糕的做事方式。

对于这种整数排序,最快的排序算法是什么?

编辑:事实证明,因为我知道数字是 1 到 5,所以我可以使用桶排序 (?) 算法,如果我没记错的话 - 我肯定会 - 意味着对于每个整数值1,我把它放在 1 组,价值 2 我把它放在 2 组等,然后在最后连接组。这似乎是一种简单而有效的方法。

但是,由于这(目前)对我来说是一个学习练习,我将消除 1 - 5 的限制并尝试实现冒泡排序和合并排序,然后比较两者,看看哪个更快。

感谢您的帮助!

【问题讨论】:

  • 你的编程语言是什么?
  • C# 或 javascript。不过,此时我并不特别担心代码中的实现。我想先了解一下算法。
  • 您是否尝试在en.wikipedia.org/wiki/Sorting_algorithm 网页上查看哪种排序算法更适合您?
  • 是的,我一直在研究算法,但由于它们非常复杂,我想知道从哪个开始,这样我才能彻底理解它。我目前正在寻找快速排序和合并排序
  • 整数 1 到 5,人。忘掉通用排序算法吧。

标签: sorting


【解决方案1】:

...有人告诉我这是一种糟糕的做事方式。

首先,不要把你从互联网上随机听到的任何消息(包括我)接受为福音。

冒泡排序在某些条件下是精细,比如当数据已经大部分排序,或者项目数比较少(比如200)(a) , 或者你没有内置在语言中的排序功能,而且你在紧迫的期限内,缺乏性能会惹恼客户,但缺乏功能会让你被解雇:-)

这种对冒泡排序的偏见类似于“函数只有一个退出点”和“无跳转”规则。您应该了解它们背后的原因,以便知道何时可以安全地忽略这些规则。

无论如何,正确的问题。针对您的特定情况的一种有效方法是只计算项目然后输出它们,例如:

dim count[1..5] = {0, 0, 0, 0, 0};
for each item in list:
    count[item] = count[item] + 1
for val in 1..5:
    for quant in 1..count[val]:
        output val

这是一个 O(n) 时间和 O(1) 空间的解决方案,对于通用排序例程,您不会找到更有效的大 O - 它只有在这种情况下才有可能,因为您拥有关于数据(仅限于值 1 到 5)。

如果您想检查所有不同的排序算法,Wikipedia Sorting Algorithm page 是一个有用的起点,包括主要算法及其属性。


(a) 顺便说一句,以下代码(使用最坏情况数据进行冒泡排序)在 CygWin 下运行在功能不太强大的 IBM T60(2GHz 双核)笔记本电脑上时,平均在 0.157 秒内完成(5 个样本:0.150、0.125、0.192、0.199、0.115)。

我不会用它来排序一百万个项目(每个人都知道冒泡排序的规模很差),但在大多数情况下 200 应该没问题:

#include <stdio.h>

#define COUNT 200
int main (void) {
    int i, swapped, tmp, item[COUNT];

    // Set up worst case (reverse order) data.

    for (i = 0; i < COUNT; i++)
        item[i] = 200 - i;

    // Slightly optimised bubble sort.

    swapped = 1;
    while (swapped) {
        swapped = 0;
        for (i = 1; i < COUNT; i++) {
            if (item[i-1] > item[i]) {
                tmp = item[i-1];
                item[i-1] = item[i];
                item[i] = tmp;
                swapped = 1;
            }
        }
    }

    // for (i = 0; i < COUNT; i++)
    //     printf ("%d ", item[i]);
    // putchar ('\n');

    return 0;
}

【讨论】:

  • 谢谢,看来它可以工作了。该算法是否具有特定名称,以便我可以对其进行更多研究?澄清一下,在 O(n) 中,n 是要排序的元素数,所以在这种情况下,意味着所需的步骤数与要排序的元素数平行?
  • @James,我称之为 PaxSort :-) 地球上的其他人可能会称之为桶排序(桶大小为 1)或计数排序。你可以从en.wikipedia.org/wiki/Counting_sort开始。
  • 哦,好吧,我想我可以坚持使用冒泡排序。我从来没有真正计时过我只是听说它的性能很差,但是 .157s 将对我当前的应用程序产生零影响,再次感谢。
【解决方案2】:

您可能不需要在这里进行排序,因为您只有 5 个可能的值。 您可以使用 5 个容器(或存储桶),并在扫描整数列表时将值放在正确的存储桶中。 最后,按顺序将桶连接在一起。

【讨论】:

  • 这是个好主意,但在我的实现中不起作用。整数实际上是一个更大的数据结构的一部分,未来将按不同的属性排序,比如按字母顺序等。目前我只是想找到按这个特定属性排序的最佳方法。
【解决方案3】:

Merge sort 是一个 O(n log n) 我认为它比 QuickSort 更好

你可以找到一些C#代码here

【讨论】:

    猜你喜欢
    • 2011-01-09
    • 2020-05-17
    • 1970-01-01
    • 2022-11-28
    • 2012-09-21
    • 2020-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多