我正在读关于快速排序的书,看不同的实现,我正试着去想一些事情。
在这个实现中(当然可以),枢轴被选为中间元素,然后左右指针相应地向右和向左移动,将元素交换到围绕枢轴的分区中。
我正在尝试数组[4,3,2,6,8,1,0]。
在第一个分区上,pivot为6,并且所有左侧元素都已小于6,因此左指针将停止在pivot处。在右侧,我们将0与6交换,然后1与8交换,因此在第一次迭代结束时,数组将如下所示:
[4, 3, 2, 0, 1, 8, 6].
然而,我的印象是,在快速排序中的每次迭代之后,支点最终会在其正确的位置,所以在这里它应该会在数组的位置5结束。
所以,有可能(也没关系)枢轴没有在正确的迭代中结束,或者是我明显遗漏了什么?
快速排序算法有许多可能的变体。在这种情况下,枢轴在迭代中不处于正确的位置是可以的。
快速排序算法的每个变体的定义特征是,在分区步骤之后,我们在数组的开头有一个部分,其中所有元素都小于或等于枢轴,在数组的结尾有一个非重叠部分,其中所有元素都大于或等于枢轴。它们之间也可能有一个部分,其中每个元素都等于枢轴。这种布局确保在使用递归调用对左部分和右部分进行排序,并保留中间部分不变后,整个数组将被排序。
请注意,在一般情况下,等于枢轴的元素可以进入数组的任何部分。快速排序的一个很好的实现,避免了最明显情况下的二次时间,即所有相等的元素,必须合理地在部分之间分配相等的元素。
可能的变体包括:
因此,快速排序的正确和高效实现是相当棘手的(还有一个问题是选择一个好的轴心点,对于这个轴心点,还存在几种具有不同权衡的方法;或者对于较小的子数组大小,优化切换到另一种非递归排序算法)。
此外,您链接到的实现似乎可以对重叠的子数组执行递归调用:
if (i <= j) {
exchange(i, j);
i++;
j--;
}
例如,当i
等于j
时,这些元素将被交换,i
将比j
大2。之后,3个元素将在以下递归调用的范围内重叠。不过,代码似乎仍然正常工作。
我正在学习快速排序在第四算法课程,罗伯特塞奇威克。 我想知道quicksort代码的以下分区是长度为n的数组中比较的个数。
假设我们将Quicksort修改为有三个分区,而不是两个分区。左侧分区的值 pivot。然后我们对左分区和右分区进行递归。这个3路分区需要多少时间? 我在一个面试问题中看到了这一点,那里的答案是O(n)。但对于普通的1次快速排序,它是O(nlogn)。 请帮我弄明白为什么不是?
我试图实现就地快速排序,最后一个元素作为我的支点。下面附上我的代码 出于某种原因,我的代码给了我一个IndexOutOfBounds异常,它不能准确地对数组排序。我不知道为什么会出现这个错误。 如果我理解正确,我们应该把最后一个元素作为我们的轴心。然后,我们将左指针向右迭代,直到找到一个大于枢轴的元素。之后,我们从右侧(继续向左移动)执行相同的操作,直到找到一个小于轴的元素。然后我们交换这些元素,
但我想知道如何选择我希望的支点,例如在这个整数列表中,8、7、1、9、11、5、6,我希望选择键6作为我代码中的支点。或者我想选9或者其他什么。我怎样才能把它写进我的代码?非常感谢任何帮助。
我在一些地方读到,如果我们不选择第一个或最后一个元素作为轴心,我们应该在分区开始之前首先将其与第一个或最后一个位置交换。所以我尝试了一个例子,我用这个算法得到了正确的分区https://www.cs.auckland.ac.nz/software/AlgAnim/qsort1a.html 此分区方法使用左指针和右指针。它将左指针移向中心,直到找到大于轴的图元。然后将右指针移向中心,直到找到一个小于
快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 Ο(nlogn) 次比较。在最坏状况下则需要 Ο(n2) 次比较,但这种状况并不常见。事实上,快速排序通常明显比其他 Ο(nlogn) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来。 快速排序使用分治法(Divide and conquer)策略来把一个串行(list)分为两