Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 有什么理由实施我自己的排序算法吗?_Sorting - Fatal编程技术网

Sorting 有什么理由实施我自己的排序算法吗?

Sorting 有什么理由实施我自己的排序算法吗?,sorting,Sorting,排序已经研究了几十年了,所以任何编程平台(java、.NET等)提供的排序算法现在一定很好吧?是否有任何理由覆盖System.Collections.SortedList之类的内容?通常没有 但是,您比那些编写排序算法的人更了解您的数据。也许你可以为你的特定数据集想出一个比一般算法更好的算法。简短回答;不,除了学术兴趣。绝对有一些时候,你对数据的深入了解可以产生比任何通用算法都更高效的排序算法。我在SO的另一篇文章中分享了这种情况的一个例子,但我将分享它,只是为了提供一个恰当的例子: 回到COB

排序已经研究了几十年了,所以任何编程平台(java、.NET等)提供的排序算法现在一定很好吧?是否有任何理由覆盖System.Collections.SortedList之类的内容?

通常没有


但是,您比那些编写排序算法的人更了解您的数据。也许你可以为你的特定数据集想出一个比一般算法更好的算法。

简短回答;不,除了学术兴趣。

绝对有一些时候,你对数据的深入了解可以产生比任何通用算法都更高效的排序算法。我在SO的另一篇文章中分享了这种情况的一个例子,但我将分享它,只是为了提供一个恰当的例子:

回到COBOL、FORTRAN等的时代。。。在一家电话公司工作的开发者必须获取一大块由活动电话号码组成的数据(我相信是在纽约市地区),然后对该列表进行排序。最初的实现使用了堆排序(这些是7位电话号码,在排序过程中发生了大量磁盘交换,因此堆排序是有意义的)

最终,开发人员偶然发现了一种不同的方法:通过意识到这一点,并且每个电话号码中只有一个可以存在于他的数据集中,他意识到他不必将实际的电话号码本身存储在内存中。相反,他将整个7位数的电话号码空间视为一个非常长的位数组(每字节8个电话号码,1000万个电话号码需要略多于一个兆字节才能捕获整个空间)。然后,他对源数据进行了一次遍历,并将找到的每个电话号码的位设置为1。然后,他最后通过位数组查找高位,并输出电话号码的排序列表

这个新算法比堆排序算法快得多(至少快1000倍),并且消耗的内存量也差不多

我想说的是,在这种情况下,开发人员开发自己的排序算法绝对有意义

如果您的应用程序都是关于排序的,并且您确实了解您的问题空间,那么您很有可能提出一种特定于应用程序的算法,该算法优于任何通用算法


然而,如果排序是应用程序的一个辅助部分,或者您只是在实现一个通用算法,那么很有可能一些非常聪明的大学类型已经提供了一种比您能够想到的任何算法都要好的算法。如果您可以在内存中保存内容,那么快速排序确实很难击败,而堆排序对于海量数据集排序非常有效(尽管我个人更喜欢使用B+树型实现来实现堆B/c,它们被调整为磁盘分页性能).

几个月前,Coding Horror博客报道某个平台的排序算法非常糟糕。如果您必须使用该平台,那么您肯定希望实现您自己的排序算法。

实现您自己的排序算法类似于优化,正如所说,“我们应该忘记小效率,比如说97%的时间:过早优化是万恶之源”.

通用排序问题已经被彻底研究过了,因此担心学术兴趣之外的问题是毫无意义的。但是,大多数排序不是在通用输入上完成的,通常可以使用数据的属性来提高排序速度

一个常见的例子是计数排序。事实证明,对于通用比较排序,O(n lg n)是我们所能希望做到的最好的

但是,假设我们知道要排序的值在固定范围内的范围,例如[a,b]。如果我们创建一个大小为b-a+1的数组(默认值为零),我们可以线性扫描数组,使用该数组存储每个元素的计数-导致线性时间排序(在数据范围内)-打破n lg n界限,但这仅仅是因为我们利用了数据的特殊属性。有关详细信息,请参见

因此,编写自己的排序算法是很有用的。注意您正在排序的内容,有时您将能够提出显著的改进。

某些库(例如Java自己的Collections.sort)根据可能适用于您或可能不适用于您的条件实现排序。例如,Collections.sort使用合并排序,因为它的O(n log(n))效率以及它是就地排序这一事实。如果两个不同的元素具有相同的值,则原始集合中的第一个元素将保持在前面(适用于对不同条件进行多次排序(首先扫描日期,然后扫描名称,集合将保持名称(然后是日期)排序)),但是,如果您想要稍微好一点的常量或具有特殊的数据集,实现您自己的快速排序或基数排序可能更有意义,因为它确切地指定了您要执行的操作

也就是说,

  • 您可能希望多线程排序实现
  • 您可能需要比Quicksorts O(n log n)更好的性能特性,例如bucketsort
  • 当默认算法使用快速排序时,您可能需要一个稳定的排序。特别是对于用户界面,您希望排序顺序保持一致
  • 对于您正在使用的数据结构,可能会有更有效的算法
  • 由于堆栈溢出,您可能需要一个默认排序算法的迭代实现(例如,您正在对大型数据集进行排序)

无限大。

如果您有实现排序算法的经验,并且了解数据特征影响其性能的方式,那么您就已经知道问题的答案了。在里面