在我看来,快速排序的一个常见实现是,该程序由一个分区子程序和两个递归调用组成,以快速排序这两个分区。
因此,在最快和伪代码中,控制流程就像这样:
quicksort[list, some parameters]
.
.
.
q=partition[some other parameters]
quicksort[1,q]
quicksort[q+1,length[list]]
.
.
.
End
q是分区后的“枢轴”。第二个快速呼叫 - 即快速排序列表的第二部分,也使用q。这是我不明白的。如果“控制流”首先通过第一个快速排序,则q将更新。在第二个快速排序中,如果需要执行所有这些分区的第二部分,那么q是如何工作的?
我认为我的误解来自伪代码的局限性。通过在伪代码中表达快速排序算法的实现,可能会遗漏一些细节。
编辑1 这似乎与我的问题有关:
For[i = 1, i < 5, i = i + 1, Print[i]]
第一次,我们会得到 i = 1,true,i = 2,1 。即使 i 更新为2, i 在 body 中仍为1(即,Print [i] = 1)。这种“控制流”是我不明白的。 当i = 1增加到2并且在它到达正文之前,它存储在哪里?
修改2
作为我想要达到的一个例子,我在这里粘贴它。 It's from here.
Partition(A,p,r)
x=A[r]
i=p+1
j=r+1
while TRUE
repeat j=j-1
until A[j]<=x
repeat i=i+1
until A[i]>=x
if i<j
then exchange A[i] with A[j]
else return j
Quicksort(A,1,length[A])
Quicksort(A,p,r)
if p<r
then q=Partition(A,p,r)
Quicksort(A,p,q)
Quicksort(A,q+1,r)
Another example can be found here.
这些算法中 q 在何时何地被放入堆栈?
答案 0 :(得分:1)
q
未更新。枢轴仍然在他的位置。在快速排序的每次迭代中,保证位于正确位置的唯一元素是枢轴。
另请注意,在递归调用期间“更改”的q
实际上并未更改,因为它是一个不同的变量,存储在不同的区域中,这是正确的,因为q
是该函数的local variable,并为每次调用生成。
编辑: [对问题编辑的回复]
在快速排序中,算法实际生成q
个数,存储在堆栈。每个变量仅在其自身的功能上“存活”,并且[仅在此示例中]可从其中访问。当函数结束时,局部变量会自动释放,所以实际上你没有一个支点,你实际上有多个支点,每个递归步骤一个。
答案 1 :(得分:0)
原来Quicksort需要额外的内存来准确运行才能完成你提到的bookeeping。也许以下(伪代码)迭代版本的算法可能会解决问题:
quicksort(array, begin, end) =
intervals_to_sort = {(begin, end)}; //a set
while there are intervals to sort:
(begin, end) = remove an interval from intervals_to_sort
if length of (begin, end) >= 2:
q = partition(array, begin, end)
add (begin, q) to intervals_to_sort
add (q+1, end) to intervals_to_sort
您可能会注意到,现在要排序的时间间隔显式保存在数据结构中(通常只是一个数组,最后插入和删除,以类似堆栈的方式),因此不存在“遗忘”的风险旧的间隔。
可能让您感到困惑的是,Quicksort最常见的描述是递归的,因此q
变量会出现多次。答案是,每次调用一个函数时,它都会创建一个 new 批量的局部变量,因此它不会触及旧的局部变量。最后,来自前一个命令性示例的显式堆栈最终被实现为具有函数变量的隐式堆栈。
(一个有趣的旁注:一些早期的编程语言没有像那样实现整齐的局部变量,而Quicksort实际上是首先使用具有显式堆栈的迭代版本来描述的。只有后者才能看到Quicksort如何优雅地被描述为Algol中的递归算法。)
对于编辑后的部分,忘记了i = 1,因为赋值会破坏性地更新变量。
答案 2 :(得分:0)
分区代码从数组中选取一些值(例如数组中点的值......示例代码选择最后一个元素) - 这是数据透视表。然后它将所有值&lt; = pivot放在左侧,所有值&gt; = pivot放在右侧,然后将pivot存储在它们之间的一个剩余槽中。此时,枢轴必须在正确的槽中,q。然后算法对分区[p,q]和分区[q + 1,r)进行排序,它们是不相交的,但覆盖了除q之外的所有A,导致整个数组被排序。