我正在阅读关于Algorithms第4版Robert Sedgewick的书中的快速排序算法。
Quicksort很受欢迎,因为它实施起来并不困难 适用于各种不同类型的输入数据,并且是 比典型的任何其他排序方法快得多 应用。快速排序算法的理想功能就是它 就地(仅使用一个小的辅助堆栈)并且它需要 时间与N log N成正比,对长度数组进行排序 N.到目前为止,我们所考虑的算法都没有结合这些算法 两个属性。
此外,quicksort的内环比其他大部分短 排序算法,这意味着它在实践中也很快 理论上。它的主要缺点是它在某种意义上是脆弱的 在实施过程中需要注意一些必须避免的问题 表现不好。
我对上述文字的疑问是
作者的意思是“只使用一个小的辅助堆栈”?
作者的意思是“quicksort的内循环比大多数其他排序算法短”?
请求用简单的例子来解释。
由于
答案 0 :(得分:1)
1作者的意思是“仅使用一个小的辅助堆栈”?
除了要排序的数据之外,作者意味着还需要很少的额外内存。因此,排序期间生成的数据结构不会产生很大的开销。
- 作者的意思是“quicksort的内循环比大多数其他排序算法短”?
醇>
作者意味着在最里面的循环中要执行的指令的数量是完全可见的,这对于例如cpu缓存。
在内部循环的下面的代码中,只有索引递增/递减。因此检查了循环条件。
作为示例,我采用了wikipedia
中提到的实现algorithm quicksort(A, lo, hi) is
if lo < hi then
p := partition(A, lo, hi)
quicksort(A, lo, p – 1)
quicksort(A, p + 1, hi)
algorithm partition(A, lo, hi) is
pivot := A[lo]
i := lo – 1
j := hi + 1
loop forever
do
i := i + 1
while A[i] < pivot
do
j := j – 1
while A[j] > pivot
if i >= j then
return j
swap A[i] with A[j]
答案 1 :(得分:1)
您还需要考虑quick-sort
是in-place
排序算法。
in-place
表示:
in-place
功能大大降低了存储要求。 因此,由于存储量小且固定,因此表示quick-sort
“只使用一个小的辅助堆栈”。
这可能意味着内部循环内部的逻辑很简单,因此需要的代码更少。这个“较短的内循环”不应与循环迭代的次数混淆。因为在任何级别的递归树上,迭代的总数仅为“n”。
答案 2 :(得分:1)
1作者的意思是“仅使用一个小的辅助堆栈”?
在理想情况下,quicksort在堆栈上使用O(log2(n))空间,在最坏的情况下,它使用堆栈上的O(n)空间,占用的空间比排序的数组多。
- 作者的意思是“quicksort的内循环比大多数其他排序算法短”?
醇>
这在现代系统上可能无关紧要,因为任何合理大小的内部循环都适合大多数处理器的代码缓存。条件分支将影响管道性能,具体取决于分支预测。
快速排序......比典型应用中的任何其他排序方法快得多。
事实并非如此,在最好的情况下,快速排序仅比合并排序稍微快一些(小于10%),而在最坏的情况下,快速排序则慢得多(O(n ^ 2)与O(n log) (N))。合并排序的主要问题是它需要一个与原始数组相同大小或1/2大小的临时数组。
答案 3 :(得分:0)
function QuickSort(Array, Left, Right)
var
L2, R2, PivotValue
begin
Stack.Push(Left, Right); // pushes Left, and then Right, on to a stack
while not Stack.Empty do
begin
Stack.Pop(Left, Right); // pops 2 values, storing them in Right and then Left
repeat
PivotValue := Array[(Left + Right) div 2];
L2 := Left;
R2 := Right;
repeat
while Array[L2] < PivotValue do // scan left partition
L2 := L2 + 1;
while Array[R2] > PivotValue do // scan right partition
R2 := R2 - 1;
if L2 <= R2 then
begin
if L2 != R2 then
Swap(Array[L2], Array[R2]); // swaps the data at L2 and R2
L2 := L2 + 1;
R2 := R2 - 1;
end;
until L2 >= R2;
if R2 - Left > Right - L2 then // is left side piece larger?
begin
if Left < R2 then
Stack.Push(Left, R2);
Left := L2;
end;
else
begin
if L2 < Right then // if left side isn't, right side is larger
Stack.Push(L2, Right);
Right := R2;
end;
until Left >= Right;
end;
end;
- 作者的意思是“仅使用一个小的辅助堆栈”?
醇>
你不需要第二个数组来存储(比如mergesort)它是在同一个内存中计算的
作者的意思是“quicksort的内循环比大多数短 其他排序算法“?
快速排序的非常快的部分是内部循环(//扫描左侧分区和//扫描右侧分区) 因为它只是增加和检查......而不是更多。