【问题标题】:Sorting singly linked vs sorting doubly linked lists [closed]排序单链表与排序双链表[关闭]
【发布时间】:2018-07-26 13:23:27
【问题描述】:

如果之前已经回答过这个问题,请指出正确的方向!

所以,在阅读有关排序的信息时,我已经在 SO 上闲逛了一段时间。然而,我想知道,为单链表和双链表(以及与数组结构相比,链接结构)选择一个好的排序算法之间的主要区别是什么?

我知道(假设我们使用 OO 语言)类型对要排序的元素等很重要(原始类型通常比复杂对象快)。我在比较 Java 字符串和整数。

据我了解,在处理链接结构时,我们可能应该排除快速排序和插入排序,因为它们涉及到很多索引。

这个问题可能很糟糕,但正如我所提到的,请指出我可以阅读有关选择正确算法的另一个来源(不是如何实现算法)。

【问题讨论】:

标签: java sorting


【解决方案1】:

是的,避免在链接结构中建立索引的想法是一个很好的指导方针。但是请注意,这不是一个严格的规则。

我知道(假设我们使用 OO 语言)类型对要排序的元素等很重要(原始类型通常比复杂对象快)。我在比较 Java 字符串和整数。

这是一个非常好的想法!原始类型具有 快速 比较时间,因此对于快速排序,这些类型运行良好(假设它们不在链接结构中)。

如果字符串很长,比较字符串可能会非常昂贵。因此,对大量字符串进行合并排序是一个好主意。所以这里的主要思想是,如果我们进行昂贵的比较,则首选合并排序。如果我们有快速比较,Quicksort 可能是首选(假设我们有一个很好的技术来选择Pivot value)。

对于链接结构,一个想法也可以是将所有列表复制到堆中,然后从那里执行Heap Sort。但如果我们的内存有限,这不是遇到问题的好方法。

如果您无法决定将一个好的排序算法应用于您的代码,请遵循语言标准。例如,请参阅此主题:Why Collections.sort uses merge sort instead of quicksort? [closed]

一个小清单:

  • 如果您不能使用更多内存:快速排序。
  • 如果您无法承受缓慢的比较:合并排序。
  • 如果您有一个非常(非常)大的结构:快速排序或合并排序。
  • 如果您有链接结构:合并排序。

当然,有很多场景组合需要仔细选择。还有很多更多的排序算法可供使用。我只提到了 Merge 和 Quick,因为您似乎很了解它们。

【讨论】:

    【解决方案2】:

    我会说没有区别。对于一般的基于比较的排序算法,您会受到 O(n) 读取和 O(log(n)) 比较的限制。

    以归并排序为例,切分列表直到达到基本情况(包含一项的列表已经排序)。然后,您正在合并和交换出现故障的项目。在单链表或双链表中交换都是 O(1) 操作。

    也许使用双向链表,如果您知道您的数据将遵循“部分排序”结构的某种顺序,例如。向前而不是向后“排序更多”,那么您可以编写列表步行以朝特定方向行走,这将产生更少的交换,但最终您仍然有一个 O(n log n) 算法,其速度非常非常快运行时间,因为只进行 O(log n) 比较,较少交换。

    【讨论】:

    • 是的,交换本身可能是 O(1)。但是当我们需要查找新索引时必须多次循环列表很慢(例如在快速排序中选择 Pivot 值后交换越来越小的元素时)。
    • @Oskarzito 不正确。在诸如合并/快速排序之类的分治算法中,该算法已经知道基于合并/分区部分已经到达需要交换的项目的事实来交换哪些项目。只有写得不好或不合适的排序才会多次遍历列表以“找到”要交换的项目(当比较已经有指向这两个项目的指针时......)
    • 是的,你有一个很好的,但它仍然是任何链接结构在其中索引的一个大问题。至于快速排序,我们必须找到一个尽可能接近中间值的好的 Pivot 值。然后我们需要交换元素以使它们出现在正确的分区中。然后再做一次(分而治之)。在一个单链表中为快速排序想象这个过程。可以这么说,这不是最佳的。
    • @Oskarzito 是的。快速排序会进行大量交换,这些交换需要对已排序的分区和未排序的列表其余部分进行额外的遍历。但是,这不是对单链表和双链表进行排序的区别。这只是 Quicksort 之类的算法和 Mergesort 之类的算法之间的区别。即便如此,只要稍微缓存指向数组中分区中元素的指针,这种差异就会消失,访问特定索引变成 O(1)。所以按理说排序单链表和双链表没有区别。
    • 啊,现在我明白你的意思了!我没有考虑那件事。所以你是说在选择高级排序算法的时候,只考虑是数组结构还是链结结构,不考虑是单链还是双链(因为都是一样的)?跨度>
    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2016-01-09
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 2014-02-04
    • 2022-01-09
    相关资源
    最近更新 更多