shell排序算法如何比合并排序算法更好?

时间:2015-10-01 12:19:16

标签: java algorithm shell sorting merge

我有关于一组书呆子的算法的这个小小的演示文稿,我随机的任务是说服他们shell排序比合并排序算法更好...我一直在阅读几乎是弱的但是不管我读了多少在合并排序和shell排序上,我发现合并排序比shell排序更好..

它们对合并排序的shell排序有什么好处吗?我的意思是在什么情况下shell排序比合并排序更好。我可能错过了一些东西,但我不知道是什么。

任何提示都可以,或者如果可能的话,你可以把我联系到有用的东西..

3 个答案:

答案 0 :(得分:4)

你必须记住提出shellort的背景:shellsort发表于1959年;快速排序,1961年; mergesort,1948年(好的,这有点令人惊讶)。当天的电脑很慢,记忆力很小。因此,与实现和代码的复杂性增加相比,mergesort的渐近优势几乎不相关。实际上,shellsort可以免费获得现代实用合并的二次回退,因为插入排序的间隙为1是插入排序。

然后不知道如何进行有效的就地合并(现在,没有人实现它,因为它在实践中效率极低)。

Shellsort有一个简单的非递归实现。高级语言中的递归仅限于LISP(当时不切实际,更不用说缺少数组类型)和尚未实现的ALGOL 60标准。

Shellsort的运行时间在大多数排序数据上有很大改善。 (虽然不是Timsort。)

答案 1 :(得分:1)

合并排序通常比shell排序快,但shell排序已到位。如果对数据进行排序,则快速排序会更快,但如果将指针或索引数组排序到数据,则合并排序通常会更快,如果元素的比较开销大于指针或索引的移动开销,因为合并排序使用较少的比较但是比快速排序更多的动作。如果对有些随机整数的数组进行排序,那么计数/基数排序是最快的。

如上所述,合并排序是在1948年发布的。旧磁带驱动程序或磁盘驱动器上实现了对旧主机的合并排序。对于磁带驱动器,存在/是合并排序的变体:

http://en.wikipedia.org/wiki/Polyphase_merge_sort

http://en.wikipedia.org/wiki/Oscillating_merge_sort

自然合并排序利用任何现有的自然排序,但具有跟踪可变大小运行的开销。对于磁带驱动器,这可以/可以使用单个文件标记来结束运行,使用双重文件标记来结束数据。具有可变大小块的早期磁盘驱动器可以实现类似的功能(使用小块来指示运行结束/数据结束)。

http://en.wikipedia.org/wiki/Merge_sort#Natural_merge_sort

自然合并排序的替代方法是时间排序,其中使用插入排序的自然和/或强制排序用于在初始传递期间创建固定大小的运行:

http://en.wikipedia.org/wiki/Timsort

"经典" merge sort是自下而上的合并排序,在外部排序的情况下,使用磁带驱动器或磁盘驱动器,初始传递对内存中的数据进行排序,跳过初始合并传递,类似于tim排序,除了内存排序可能没有插入排序,并且通常对指针或索引的数组进行排序,并且根据这些指针或索引编写数据,而不是在写入之前对存储器中的数据进行排序。在某些系统上,使用了具有多个指针/数据长度的单个I / O. SATA / IDE / SCSI PC控制器有一组描述符,用于保存地址/长度数据以处理分页内存,但我不知道PC的任何高端分类程序是否使用描述符来编写合并排序的记录集与单个I / O.

我不确定自上而下合并排序是否首次发布。它不是从一些固定或可变的运行大小开始,而是在合并运行时使用迭代来推进索引或指针,而是递归地生成索引或指针,直到它们代表一些小的固定运行大小,通常是运行大小为1,然后才会执行任何操作实际合并数据。无论运行合并的深度第一/左第一个排序的缓存本地化可能存在什么优势,它都会被递归的开销所抵消,并且通常自顶向下合并排序比自下而上合并排序稍慢(约5%)

答案 2 :(得分:0)

这取决于您对"更好"的定义,但如果您查看常用的指标 - 最差情况下的性能 - 合并排序(O(n log n))实际上是大型列表比shell排序更快(O(n^2))。

空间复杂性而言,两者都可以在就地中实现,因此shell排序也没有优势。