mirror of
https://github.com/krahets/hello-algo.git
synced 2026-04-13 18:00:18 +08:00
add Q&A of hashing, heap, sorting and tree chapter (#564)
* add`Q&A` of `stack_and_queue` chapter * Update summary.md * Update summary.md * add`Q&A` of `hashing` chapter * add`Q&A` of `hashing` chapter * add`Q&A` of `hashing` chapter * add`Q&A` of `tree` chapter * add`Q&A` of `heap` chapter * Update summary.md * add`Q&A` of `sorting` chapter * Update summary.md * Update summary.md * Update summary.md --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
@@ -14,6 +14,14 @@
|
||||
|
||||
## Q & A
|
||||
|
||||
!!! question "排序算法稳定性在什么情况下是必须的?"
|
||||
|
||||
在现实中,我们有可能是在对象的某个属性上进行排序。例如,学生有姓名和身高两个属性,我们希望实现一个多级排序/
|
||||
|
||||
先按照姓名进行排序,得到 `(A, 180) (B, 185) (C, 170) (D, 170)` ;接下来对身高进行排序。由于排序算法不稳定,我们可能得到 `(D, 170) (C, 170) (A, 180) (B, 185)` 。
|
||||
|
||||
可以发现,学生 D 和 C 的位置发生了交换,姓名的有序性被破坏了,而这是我们不希望看到的。
|
||||
|
||||
!!! question "哨兵划分中“从右往左查找”与“从左往右查找”的顺序可以交换吗?"
|
||||
|
||||
不行,当我们以最左端元素为基准数时,必须先“从右往左查找”再“从左往右查找”。这个结论有些反直觉,我们来剖析一下原因。
|
||||
@@ -23,3 +31,13 @@
|
||||
举个例子,给定数组 `[0, 0, 0, 0, 1]` ,如果先“从左向右查找”,哨兵划分后数组为 `[1, 0, 0, 0, 0]` ,这个结果是不正确的。
|
||||
|
||||
再深入思考一下,如果我们选择 `nums[right]` 为基准数,那么正好反过来,必须先“从左往右查找”。
|
||||
|
||||
!!! question "关于尾递归优化,为什么选短的数组能保证递归深度不超过 $log n$ ?"
|
||||
|
||||
递归深度就是当前未返回的递归方法的数量。每轮哨兵划分我们将原数组划分为两个子数组。在尾递归优化后,向下递归的子数组长度最大为原数组的一半长度。假设最差情况,一直为一半长度,那么最终的递归深度就是 $log n$ 。
|
||||
|
||||
回顾原始的快速排序,我们有可能会连续地递归长度较大的数组,最差情况下为 $n, n - 1, n - 2, ..., 2, 1$ ,从而递归深度为 $n$ 。尾递归优化可以避免这种情况的出现。
|
||||
|
||||
!!! question "桶排序的最差时间复杂度为什么是 $O(n^2)$ ?"
|
||||
|
||||
最差情况下,所有元素被分至同一个桶中。如果我们采用一个 $O(n^2)$ 算法来排序这些元素,则时间复杂度为 $O(n^2)$ 。
|
||||
|
||||
Reference in New Issue
Block a user