This commit is contained in:
krahets
2023-08-21 19:32:49 +08:00
parent c0f960b443
commit c359c07fe0
67 changed files with 443 additions and 442 deletions
+5 -4
View File
@@ -3454,14 +3454,13 @@
<h1 id="115">11.5 &nbsp; 快速排序<a class="headerlink" href="#115" title="Permanent link">&para;</a></h1>
<p>「快速排序 quick sort」是一种基于分治思想的排序算法,运行高效,应用广泛。</p>
<p>快速排序的核心操作是“哨兵划分”,其目标是:选择数组中的某个元素作为“基准数”,将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。具体来说,哨兵划分的流程为:</p>
<p>「快速排序 quick sort」是一种基于分治策略的排序算法,运行高效,应用广泛。</p>
<p>快速排序的核心操作是“哨兵划分”,其目标是:选择数组中的某个元素作为“基准数”,将所有小于基准数的元素移到其左侧,而大于基准数的元素移到其右侧。具体来说,哨兵划分的流程如下图所示。</p>
<ol>
<li>选取数组最左端元素作为基准数,初始化两个指针 <code>i</code><code>j</code> 分别指向数组的两端。</li>
<li>设置一个循环,在每轮中使用 <code>i</code><code>j</code>)分别寻找第一个比基准数大(小)的元素,然后交换这两个元素。</li>
<li>循环执行步骤 <code>2.</code> ,直到 <code>i</code><code>j</code> 相遇时停止,最后将基准数交换至两个子数组的分界线。</li>
</ol>
<p>哨兵划分完成后,原数组被划分成三部分:左子数组、基准数、右子数组,且满足“左子数组任意元素 <span class="arithmatex">\(\leq\)</span> 基准数 <span class="arithmatex">\(\leq\)</span> 右子数组任意元素”。因此,我们接下来只需对这两个子数组进行排序。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:9"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" name="__tabbed_1" type="radio" /><input id="__tabbed_1_3" name="__tabbed_1" type="radio" /><input id="__tabbed_1_4" name="__tabbed_1" type="radio" /><input id="__tabbed_1_5" name="__tabbed_1" type="radio" /><input id="__tabbed_1_6" name="__tabbed_1" type="radio" /><input id="__tabbed_1_7" name="__tabbed_1" type="radio" /><input id="__tabbed_1_8" name="__tabbed_1" type="radio" /><input id="__tabbed_1_9" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">&lt;1&gt;</label><label for="__tabbed_1_2">&lt;2&gt;</label><label for="__tabbed_1_3">&lt;3&gt;</label><label for="__tabbed_1_4">&lt;4&gt;</label><label for="__tabbed_1_5">&lt;5&gt;</label><label for="__tabbed_1_6">&lt;6&gt;</label><label for="__tabbed_1_7">&lt;7&gt;</label><label for="__tabbed_1_8">&lt;8&gt;</label><label for="__tabbed_1_9">&lt;9&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -3495,8 +3494,9 @@
</div>
<p align="center"> 图:哨兵划分步骤 </p>
<p>哨兵划分完成后,原数组被划分成三部分:左子数组、基准数、右子数组,且满足“左子数组任意元素 <span class="arithmatex">\(\leq\)</span> 基准数 <span class="arithmatex">\(\leq\)</span> 右子数组任意元素”。因此,我们接下来只需对这两个子数组进行排序。</p>
<div class="admonition note">
<p class="admonition-title">快速排序的分治思想</p>
<p class="admonition-title">快速排序的分治策略</p>
<p>哨兵划分的实质是将一个较长数组的排序问题简化为两个较短数组的排序问题。</p>
</div>
<div class="tabbed-set tabbed-alternate" data-tabs="2:12"><input checked="checked" id="__tabbed_2_1" name="__tabbed_2" type="radio" /><input id="__tabbed_2_2" name="__tabbed_2" type="radio" /><input id="__tabbed_2_3" name="__tabbed_2" type="radio" /><input id="__tabbed_2_4" name="__tabbed_2" type="radio" /><input id="__tabbed_2_5" name="__tabbed_2" type="radio" /><input id="__tabbed_2_6" name="__tabbed_2" type="radio" /><input id="__tabbed_2_7" name="__tabbed_2" type="radio" /><input id="__tabbed_2_8" name="__tabbed_2" type="radio" /><input id="__tabbed_2_9" name="__tabbed_2" type="radio" /><input id="__tabbed_2_10" name="__tabbed_2" type="radio" /><input id="__tabbed_2_11" name="__tabbed_2" type="radio" /><input id="__tabbed_2_12" name="__tabbed_2" type="radio" /><div class="tabbed-labels"><label for="__tabbed_2_1">Java</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Python</label><label for="__tabbed_2_4">Go</label><label for="__tabbed_2_5">JS</label><label for="__tabbed_2_6">TS</label><label for="__tabbed_2_7">C</label><label for="__tabbed_2_8">C#</label><label for="__tabbed_2_9">Swift</label><label for="__tabbed_2_10">Zig</label><label for="__tabbed_2_11">Dart</label><label for="__tabbed_2_12">Rust</label></div>
@@ -3793,6 +3793,7 @@
</div>
</div>
<h2 id="1151">11.5.1 &nbsp; 算法流程<a class="headerlink" href="#1151" title="Permanent link">&para;</a></h2>
<p>快速排序的整体流程如下图所示。</p>
<ol>
<li>首先,对原数组执行一次“哨兵划分”,得到未排序的左子数组和右子数组。</li>
<li>然后,对左子数组和右子数组分别递归执行“哨兵划分”。</li>