From 501502662c35a25a12c59246b9a49d0db0841df2 Mon Sep 17 00:00:00 2001 From: krahets Date: Mon, 20 Mar 2023 03:14:21 +0800 Subject: [PATCH] Update quick_sort.md --- docs/chapter_sorting/quick_sort.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/chapter_sorting/quick_sort.md b/docs/chapter_sorting/quick_sort.md index c4c6da1e5..3817f62dc 100755 --- a/docs/chapter_sorting/quick_sort.md +++ b/docs/chapter_sorting/quick_sort.md @@ -115,6 +115,16 @@ [class]{QuickSort}-[func]{partition} ``` +!!! question "“从右往左查找”与“从左往右查找”顺序可以交换吗?" + + 不行,当我们以最左端元素为基准数时,必须先“从右往左查找”再“从左往右查找”。这个结论有些反直觉,我们来剖析一下原因。 + + 哨兵划分 `partition()` 的最后一步是交换 `nums[left]` 和 `nums[i]` ,完成交换后,基准数左边的元素都 `<=` 基准数,**这就要求最后一步交换前 `nums[left] >= nums[i]` 必须成立**。假设我们先“从左往右查找”,那么如果找不到比基准数更小的元素,**则会在 `i == j` 时跳出循环,此时可能 `nums[j] == nums[i] > nums[left]`** ;也就是说,此时最后一步交换操作会把一个比基准数更大的元素交换至数组最左端,导致哨兵划分失败。 + + 举个例子,给定数组 `[0, 0, 0, 0, 1]` ,如果先“从左向右查找”,哨兵划分后数组为 `[1, 0, 0, 0, 0]` ,这个结果是不对的。 + + 再深想一步,如果我们选择 `nums[right]` 为基准数,那么正好反过来,必须先“从左往右查找”。 + ## 算法流程 1. 首先,对数组执行一次「哨兵划分」,得到待排序的 **左子数组** 和 **右子数组**;