何时需要实现自己的排序算法?

7

如果这是一个愚蠢的问题,请原谅我……但是我回想起我的计算机科学课程,我清楚地记得学习/被测试了几种排序算法和相应的“大O”符号。

然而,在课堂之外,我从未真正编写过排序代码。

当我从数据库中获取结果时,我使用“Order By”。否则,我使用实现了排序的集合类。我已经实现了IComparable以允许排序;但是我从未超越过那个。

对于我们这些不实现语言/框架的人来说,排序始终只是一种学术追求吗?还是现代语言在现代硬件上运行使它成为一个微不足道的细节?

最后,当我在List(Of String)上调用.Sort时,底层使用的是什么排序算法?


3
除非你在使用没有第三方库的低级语言,否则几乎不需要实现自己的排序例程。 - Oliver Charlesworth
10个回答

4

尽管你很少需要自己实现排序算法,但了解不同算法及其复杂度可能有助于你解决更复杂的问题。

最后,当我在 List(Of String) 上调用 .Sort 时,底层使用的是哪种排序算法?

快速排序


3

自从我在大学里上计算机课以来,我从未实现过自己的排序算法,如果我曾经考虑过写自己的算法,我会先检查一下我的头。

List<T>根据MSDN文档使用快速排序:

http://msdn.microsoft.com/en-us/library/b0zbh7b6.aspx


2
你使用高级语言时,可能不需要实现自己的排序算法...
在课堂上所学的只是为了教你大O(omicron)符号的存在和重要性。
它告诉你优化始终是编程的目标,当你编写代码时必须考虑它的执行方式。
它教你循环嵌套和递归可能会导致性能问题,如果在编码之前没有进行充分的分析/优化。
它是一个指南,可以在设计之前检查并近似计算执行速度。

2

作为程序员,了解这些算法的工作原理非常重要。其中一个原因是,在某些情况下,某些算法更好,尽管排序很少成为瓶颈。

在某些框架中,.Sort函数根据情况使用不同的方法。


1
  1. 现代语言在现代硬件上运行,使得担心排序成为微不足道的细节,除非分析器显示排序是您代码的瓶颈。
  2. 根据this,List.Sort使用Array.Sort,而Array.Sort使用QuickSort。

1

在我看来,这已经成为了一种学术练习。你需要理解算法复杂度,排序是一个很好的例子,因为你可以很容易地看到结果并计算不同的复杂度。然而,在现实生活中,几乎肯定有一个库调用可以比你自己编写的更快地对范围进行排序。

我不知道 .Net 库在其默认实现中使用了什么,但我猜测它可能是快速排序或希尔排序。如果是其他东西,我会很感兴趣去发现。


1

我偶尔需要编写自己的排序方法,但只有在编写相对不成熟和性能较弱的平台时才需要(例如 Windows CE 中的 .Net 1.1 或嵌入式 Java 等)。

在任何类似于现代计算机的设备上,最好的排序算法是 T-SQL 中的 ORDER BY 子句。


1

实现自己的排序算法是为了深入了解算法的工作原理、权衡利弊、了解哪些经过验证的方法可以高效地解决各种问题等等。

正如Darin Dimitrov的回答所述,库排序例程需要具有非常竞争力的平均情况性能,因此通常选择快速排序。


1
对于那些不实现语言/框架的人来说,排序是否一直只是学术追求?还是现代语言在现代硬件上运行使得它成为一个微不足道的细节?即使您没有实现自己的程序,您可能也知道数据的排列方式,并且可能希望选择适当的库算法。例如,请参见关于几乎排序数据的此讨论

-2

我认为有时候你需要有一个自定义排序方法。 如果你想按汽车品牌进行排序,但不是按字母顺序呢? 例如,你有一个包含以下汽车品牌的数据库:本田(Honda)、雷克萨斯(Lexus)、丰田(Toyota)、讴歌(Acura)、日产(Nissan)和英菲尼迪(Infiniti)

如果你使用普通的排序,你会得到这个顺序:讴歌、福特(Ford)、本田、现代(Hyundai)、雷克萨斯、丰田

如果你想按照汽车公司的标准和豪华级别将它们排序呢?那就是:雷克萨斯、丰田、本田、讴歌、日产、英菲尼迪。

我认为在这种情况下,你需要一个自定义排序方法。


3
不会的。您需要编写一个自定义比较器(或使用接受项目投影进行排序的排序算法,如LINQ的“OrderBy”方法),但排序算法本身将是相同的。 - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接