为什么我们不在链表上使用快速排序?

时间:2017-11-30 18:44:13

标签: algorithm sorting time-complexity

快速排序算法可分为以下几个步骤

1)确定枢轴。

2)根据数据透视分区链表。

3)递归地将链表分成两部分。

现在,如果我总是选择最后一个元素作为枢轴,那么识别枢轴元素(第一步)需要O(n)时间。

识别出枢轴元素后,我们可以存储它的数据并将其与所有其他元素进行比较,以识别正确的分区点(第2步)。当我们存储数据透视数据时,每次比较将花费O(1)时间,并且每次交换需要O(1)时间。所以总共n个元素花费O(n)时间。

所以递归关系是

T(n)= 2T(n / 2)+ n为O(nlogn),与链表合并排序相同。

那么为什么合并排序比链接列表的快速排序更受欢迎?

2 个答案:

答案 0 :(得分:2)

  

因此递归关系是...... O(nlogn)

最差的数组快速排序是O(n ^ 2),例如,每个递归级别只会将最大分区的大小减少1或2(如果不包含在任一分区中,则为2)。

  

那么为什么合并排序比链接列表的快速排序更受欢迎?

它要快得多,尤其是自下而上的合并排序,它可以消除扫描列表以进行拆分。相反,它使用一个小的(26到32)内部指针数组或对节点(或小数组列表)的引用,将节点合并到数组中,然后合并数组以创建排序列表。 Wiki文章包含伪代码:

https://en.wikipedia.org/wiki/Merge_sort#Bottom-up_implementation_using_lists

答案 1 :(得分:1)

  

现在,如果我总是选择最后一个元素作为枢轴,那么识别枢轴   element(第1步)需要O(n)时间。

实际上需要O(1)时间。但无论如何,一个常见的误解是w.r.t。快速排序是指您可以选择预定义元素作为枢轴,而不是随机。你可能没有。

快速排序在O(N log(N))中平均工作,但最坏情况是O(N ^ 2)。现在,当随机选择枢轴并在大型集合上执行算法时 - 实际上O(N log(N))就是你在实践中得到的。但是,如果您选择预定义的数据透视表,那么,根据您的数据模式,您可以轻松地遇到最坏情况。 认为源数据随机,它来自某些来源,并展示了一些模式。

例如,如果您将最后一个元素作为数据透视表,并且您的源数据以防万一已经按相反的顺序排序 - 那么您肯定会得到O(N的简并情况) ^ 2)。

关于您的问题,为什么通常不会对链接列表使用快速排序。原因(恕我直言)是对于列表,合并排序是首选方式。它保证了O(N log(N))的最坏情况性能。它通常不用于数组,因为在数组的情况下它需要额外的内存分配,但链接列表不是这种情况。