algorithm - Quicksort - 哪个子部分应该首先排序?

标签 algorithm sorting quicksort

我正在阅读一些关于两个递归快速排序调用的顺序的文本:

... it is important to call the smaller subproblem first, this in conjunction with tail recursion ensures that the stack depth is log n.

我完全不确定那是什么意思,为什么我应该先在较小的子数组上调用快速排序?

最佳答案

将快速排序视为隐式二叉树。枢轴是根,左右子树是您创建的分区。

现在考虑对这棵树进行深度优先搜索。递归调用实际上对应于对上述隐式树进行深度优先搜索。还假设树总是有较小的子树作为左子树,所以建议实际上是在这棵树上进行预排序。

现在假设您使用堆栈实现预序,您只压入左子节点(但将父节点保留在堆栈中),并且在需要时压入右子节点(假设您保持一种状态,您知道节点是否探索了它的左子节点),您替换堆栈的顶部,而不是压入右子节点(这对应于尾递归部分)。

最大堆栈深度是最大“左深度”:即,如果您将每条通往左 child 的边标记为 1,将前往右 child 的每条边标记为 0,那么您正在查看具有最大边和的路径(基本上你不计算右边缘)。

现在,由于左子树的元素不超过一半,每次向左移动(即遍历和标记为 1 的边),您都会将要探索的节点数减少至少一半。

因此,您看到的标记为 1 的边的最大数量不超过 log n。

因此,如果您始终选择较小的分区并使用尾递归,则堆栈使用量不会超过 log n。

关于algorithm - Quicksort - 哪个子部分应该首先排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12792738/

相关文章:

使用递归的python快速排序

javascript - 使用 jQuery 从 JSON 文件中仅选择前 10 个值

javascript - 冒泡排序只对数组的一部分进行排序

c - 使用快速排序对带有指针的数组进行排序

c - 变量乘法的优化

ios - Swift:按多个条件对嵌套数组进行分组 - 改进算法

javascript - 开发自己的 "Hash"算法

JavaScript 对列表进行限制排序

c++ - QuickSort 比 std::sort 慢

c++ - 与 Mergesort 相比,为什么 GNU 并行快速排序这么慢?