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:
Sizhuo Long
2023-06-25 22:50:20 +10:00
committed by GitHub
parent 504dff1728
commit efc1c2f49f
4 changed files with 76 additions and 0 deletions

View File

@@ -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)$ 。