排序已经研究了几十年,所以现在任何编程平台(java,.NET等)提供的排序算法肯定都不错,对吧?有没有理由覆盖像System.Collections.SortedList?
这样的东西答案 0 :(得分:17)
绝对有时候,您对数据的深入了解可以产生比任何通用算法更高效的排序算法。我在SO的另一篇文章中分享了这种情况的一个例子,但我会分享它只是为了提供一个案例:
回到COBOL,FORTRAN等的日子......一家为电话公司工作的开发人员不得不接受一大堆由活跃电话号码组成的数据(我相信它是在纽约市区) ,并对该列表进行排序。最初的实现使用堆排序(这些是7位数的电话号码,并且在排序期间进行了大量的磁盘交换,因此堆排序很有意义。)
最终,开发人员偶然发现了一种不同的方法:通过实现这一方法,并且每个电话号码中只有一个存在于他的数据集中,他意识到他不必将实际的电话号码存储在内存中。相反,他将整个7位数的电话号码空间视为一个非常长的阵列(每个字节8个电话号码,1000万个电话号码只需要超过1兆的电流来捕获整个空间)。然后,他通过他的源数据进行了一次传递,并将他找到的每个电话号码的位设置为1.然后,他通过位数组最后通过寻找高位并输出已分类的电话号码列表。
这种新算法比堆排序算法快得多(速度至少快1000倍),并消耗了大约相同的内存量。
我想说,在这种情况下,开发人员开发自己的排序算法绝对有意义。
如果您的应用程序完全是关于排序,并且您确实知道您的问题空间,那么您很有可能提出一种特定于应用程序的算法,该算法胜过任何通用算法。
但是,如果排序是您的应用程序的辅助部分,或者您只是实现了一个通用算法,那么一些非常聪明的大学类型已经提供了比您将要做的更好的算法的机会非常非常好。能够拿出来。如果你可以在内存中保存内容,快速排序真的很难被击败,并且堆排序对于大规模数据集排序非常有效(尽管我个人更喜欢使用B + C类型的实现用于堆b / c它们被调整到磁盘分页性能)。
答案 1 :(得分:9)
一般没有。
但是,您比编写这些排序算法的人更了解您的数据。也许您可以为您的特定数据集提出一种比通用算法更好的算法。
答案 2 :(得分:3)
实现你自己的排序算法类似于优化,正如Sir Charles Antony Richard Hoare所说,“我们应该忘记小的效率,比如大约97%的时间:过早的优化是所有邪恶的根源。”
答案 3 :(得分:2)
某些库(例如Java自己的Collections.sort)根据可能适用于您的条件实施排序,也可能不适用于您。例如,Collections.sort对它的O(n log(n))效率使用合并排序以及它是就地排序的事实。如果两个不同的元素具有相同的值,则原始集合中的第一个元素保留在前面(适用于不同条件的多遍排序(第一次扫描日期,然后是名称,集合保持名称(然后是日期)排序))但是,如果你想要稍微好一些的常量或者有一个特殊的数据集,那么实现你自己的快速排序或基数排序可能更有意义,特别是你想要做的事情。
答案 4 :(得分:1)
简短回答;不,除了学术兴趣。
答案 5 :(得分:1)
Ad无限。
答案 6 :(得分:0)
几个月前,Coding Horror博客在某个平台上报道了一个非常糟糕的排序算法。如果您必须使用该平台,那么您确实希望实现自己的平台。
答案 7 :(得分:0)
通用分拣的问题已经被研究到地狱和背部,所以担心学术兴趣之外是没有意义的。但是,大多数排序不是在通用输入上完成的,通常您可以使用数据属性来提高排序速度。
一个常见的例子是计数排序。事实证明,对于通用比较排序,O(n lg n)是我们所希望做的最好的。
但是,假设我们知道要排序的值在固定范围内的范围,比如[a,b]。如果我们创建一个大小为b的数组 - a + 1(将所有内容默认为零),我们可以线性扫描数组,使用此数组存储每个元素的计数 - 从而产生线性时间排序(在数据范围内) ) - 打破n lg n bound,但这只是因为我们正在利用我们数据的特殊属性。有关更多详细信息,请参阅here。
所以是的,编写自己的排序算法很有用。注意你要分类的东西,你有时会得到显着的改进。
答案 8 :(得分:0)
如果您有实施排序算法的经验并了解数据特征影响其性能的方式,那么您就已经知道了问题的答案。换句话说,你已经知道像QuickSort这样的东西在几乎排序的列表中具有行人表现。 :-)如果你在某些结构中有你的数据,那么某种排序(几乎)是免费的。等
否则,不。