在最坏的情况下,快速排序递归深度需要 O(n) 的堆栈空间。为什么在最坏的情况下它不会导致大型集合的堆栈溢出?(倒序)
问问题
2258 次
3 回答
6
如果您在枢轴的两侧进行递归,那么在最坏的情况下,对于足够大的数据,它确实会导致堆栈溢出。这就是为什么没有人在生产代码中使用天真的 QuickSort。
您可以对算法进行一个简单的更改,以防止Omega(n)
最坏情况下的堆栈使用。在每个分区之后,递归地对“小半部分”进行快速排序,然后迭代循环以完成“大半部分”。这需要O(log n)
额外的堆栈空间。如果你愿意,你可以通过再次修改它使其成为O(1)
堆栈空间和O(log n)
额外的非堆栈空间。将“大半部分”推到预先分配的数组(或您选择的其他后进先出数据结构)的末尾,循环执行“小半部分”,当您击中底部时弹出最后一个元素关闭数据结构来做下一步。
您可以进行进一步的更改以避免Omega(n^2)
最坏情况下的运行时间。但它不再是一个简单的快速排序,它是一个带有中位数的中位数枢轴选择的快速排序,或者一个 Introsort,或者其他什么。
于 2012-10-19T09:12:43.493 回答
1
在顺序相反的情况下(最坏的情况),它可能会导致堆栈溢出。因为数组对于内部函数堆栈来说可能太大了。(例如 99,000,000 个元素)您可以将递归替换为stack
数据结构。你会循环while (stck.empty() == false)
function quicksort(arr[0,1,...n-1])
stack.push(pair(0, n - 1))
while stack not empty
interval = stack.pop()
...
...
stack.push(interval(0, pivot - 1))
stack.push(interval(pivot + 1, n - 1))
于 2012-10-19T08:57:25.017 回答