This commit is contained in:
krahets
2023-12-28 17:18:44 +08:00
parent 5e0d7327db
commit b8a5bd790b
114 changed files with 860 additions and 863 deletions
+1 -1
View File
@@ -1697,7 +1697,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1857,7 +1857,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3671,7 +3671,7 @@
<!-- Page content -->
<h1 id="41">4.1 &nbsp; 数组<a class="headerlink" href="#41" title="Permanent link">&para;</a></h1>
<p>「数组 array」是一种线性数据结构,其将相同类型的元素存储在连续的内存空间中。我们将元素在数组中的位置称为该元素的「索引 index」。图 4-1 展示了数组的主要术语和概念。</p>
<p>「数组 array」是一种线性数据结构,其将相同类型的元素存储在连续的内存空间中。我们将元素在数组中的位置称为该元素的「索引 index」。图 4-1 展示了数组的主要概念和存储方式</p>
<p><a class="glightbox" href="../array.assets/array_definition.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="数组定义与存储方式" class="animation-figure" src="../array.assets/array_definition.png" /></a></p>
<p align="center"> 图 4-1 &nbsp; 数组定义与存储方式 </p>
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1848,7 +1848,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3662,8 +3662,8 @@
<p>观察图 4-5 ,链表的组成单位是「节点 node」对象。每个节点都包含两项数据:节点的“值”和指向下一节点的“引用”。</p>
<ul>
<li>链表的首个节点被称为“头节点”,最后一个节点被称为“尾节点”。</li>
<li>尾节点指向的是“空”,它在 Java、C++ 和 Python 中分别被记为 <span class="arithmatex">\(\text{null}\)</span><span class="arithmatex">\(\text{nullptr}\)</span><span class="arithmatex">\(\text{None}\)</span></li>
<li>在 C、C++、Go 和 Rust 等支持指针的语言中,上述“引用”应被替换为“指针”。</li>
<li>尾节点指向的是“空”,它在 Java、C++ 和 Python 中分别被记为 <code>null</code><code>nullptr</code><code>None</code></li>
<li>在 C、C++、Go 和 Rust 等支持指针的语言中,上述“引用”应被替换为“指针”。</li>
</ul>
<p>如以下代码所示,链表节点 <code>ListNode</code> 除了包含值,还需额外保存一个引用(指针)。因此在相同数据量下,<strong>链表比数组占用更多的内存空间</strong></p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
@@ -4654,7 +4654,7 @@
<h2 id="423">4.2.3 &nbsp; 常见链表类型<a class="headerlink" href="#423" title="Permanent link">&para;</a></h2>
<p>如图 4-8 所示,常见的链表类型包括三种。</p>
<ul>
<li><strong>单向链表</strong>:即前面介绍的普通链表。单向链表的节点包含值和指向下一节点的引用两项数据。我们将首个节点称为头节点,将最后一个节点称为尾节点,尾节点指向空 <span class="arithmatex">\(\text{None}\)</span></li>
<li><strong>单向链表</strong>:即前面介绍的普通链表。单向链表的节点包含值和指向下一节点的引用两项数据。我们将首个节点称为头节点,将最后一个节点称为尾节点,尾节点指向空 <code>None</code></li>
<li><strong>环形链表</strong>:如果我们令单向链表的尾节点指向头节点(首尾相接),则得到一个环形链表。在环形链表中,任意节点都可以视作头节点。</li>
<li><strong>双向链表</strong>:与单向链表相比,双向链表记录了两个方向的引用。双向链表的节点定义同时包含指向后继节点(下一个节点)和前驱节点(上一个节点)的引用(指针)。相较于单向链表,双向链表更具灵活性,可以朝两个方向遍历链表,但相应地也需要占用更多的内存空间。</li>
</ul>
+32 -32
View File
@@ -1839,7 +1839,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4385,7 +4385,7 @@
<a id="__codelineno-72-18" name="__codelineno-72-18" href="#__codelineno-72-18"></a>
<a id="__codelineno-72-19" name="__codelineno-72-19" href="#__codelineno-72-19"></a> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">index</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-72-20" name="__codelineno-72-20" href="#__codelineno-72-20"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;访问元素&quot;&quot;&quot;</span>
<a id="__codelineno-72-21" name="__codelineno-72-21" href="#__codelineno-72-21"></a> <span class="c1"># 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-72-21" name="__codelineno-72-21" href="#__codelineno-72-21"></a> <span class="c1"># 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-72-22" name="__codelineno-72-22" href="#__codelineno-72-22"></a> <span class="k">if</span> <span class="n">index</span> <span class="o">&lt;</span> <span class="mi">0</span> <span class="ow">or</span> <span class="n">index</span> <span class="o">&gt;=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span><span class="p">:</span>
<a id="__codelineno-72-23" name="__codelineno-72-23" href="#__codelineno-72-23"></a> <span class="k">raise</span> <span class="ne">IndexError</span><span class="p">(</span><span class="s2">&quot;索引越界&quot;</span><span class="p">)</span>
<a id="__codelineno-72-24" name="__codelineno-72-24" href="#__codelineno-72-24"></a> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_arr</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
@@ -4428,12 +4428,12 @@
<a id="__codelineno-72-61" name="__codelineno-72-61" href="#__codelineno-72-61"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_arr</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_arr</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span>
<a id="__codelineno-72-62" name="__codelineno-72-62" href="#__codelineno-72-62"></a> <span class="c1"># 更新元素数量</span>
<a id="__codelineno-72-63" name="__codelineno-72-63" href="#__codelineno-72-63"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-72-64" name="__codelineno-72-64" href="#__codelineno-72-64"></a> <span class="c1"># 返回被删除元素</span>
<a id="__codelineno-72-64" name="__codelineno-72-64" href="#__codelineno-72-64"></a> <span class="c1"># 返回被删除元素</span>
<a id="__codelineno-72-65" name="__codelineno-72-65" href="#__codelineno-72-65"></a> <span class="k">return</span> <span class="n">num</span>
<a id="__codelineno-72-66" name="__codelineno-72-66" href="#__codelineno-72-66"></a>
<a id="__codelineno-72-67" name="__codelineno-72-67" href="#__codelineno-72-67"></a> <span class="k">def</span> <span class="nf">extend_capacity</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a id="__codelineno-72-68" name="__codelineno-72-68" href="#__codelineno-72-68"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;列表扩容&quot;&quot;&quot;</span>
<a id="__codelineno-72-69" name="__codelineno-72-69" href="#__codelineno-72-69"></a> <span class="c1"># 新建一个长度为原数组 __extend_ratio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-72-69" name="__codelineno-72-69" href="#__codelineno-72-69"></a> <span class="c1"># 新建一个长度为原数组 _extend_ratio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-72-70" name="__codelineno-72-70" href="#__codelineno-72-70"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_arr</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_arr</span> <span class="o">+</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span><span class="p">()</span> <span class="o">*</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_extend_ratio</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-72-71" name="__codelineno-72-71" href="#__codelineno-72-71"></a> <span class="c1"># 更新列表容量</span>
<a id="__codelineno-72-72" name="__codelineno-72-72" href="#__codelineno-72-72"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_capacity</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_arr</span><span class="p">)</span>
@@ -4475,7 +4475,7 @@
<a id="__codelineno-73-29" name="__codelineno-73-29" href="#__codelineno-73-29"></a>
<a id="__codelineno-73-30" name="__codelineno-73-30" href="#__codelineno-73-30"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-73-31" name="__codelineno-73-31" href="#__codelineno-73-31"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-73-32" name="__codelineno-73-32" href="#__codelineno-73-32"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-73-32" name="__codelineno-73-32" href="#__codelineno-73-32"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-73-33" name="__codelineno-73-33" href="#__codelineno-73-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">size</span><span class="p">())</span>
<a id="__codelineno-73-34" name="__codelineno-73-34" href="#__codelineno-73-34"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="n">out_of_range</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">);</span>
<a id="__codelineno-73-35" name="__codelineno-73-35" href="#__codelineno-73-35"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">arr</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
@@ -4525,7 +4525,7 @@
<a id="__codelineno-73-79" name="__codelineno-73-79" href="#__codelineno-73-79"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-73-80" name="__codelineno-73-80" href="#__codelineno-73-80"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-73-81" name="__codelineno-73-81" href="#__codelineno-73-81"></a><span class="w"> </span><span class="n">arrSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-73-82" name="__codelineno-73-82" href="#__codelineno-73-82"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-73-82" name="__codelineno-73-82" href="#__codelineno-73-82"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-73-83" name="__codelineno-73-83" href="#__codelineno-73-83"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-73-84" name="__codelineno-73-84" href="#__codelineno-73-84"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-73-85" name="__codelineno-73-85" href="#__codelineno-73-85"></a>
@@ -4581,7 +4581,7 @@
<a id="__codelineno-74-22" name="__codelineno-74-22" href="#__codelineno-74-22"></a>
<a id="__codelineno-74-23" name="__codelineno-74-23" href="#__codelineno-74-23"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-74-24" name="__codelineno-74-24" href="#__codelineno-74-24"></a><span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-74-25" name="__codelineno-74-25" href="#__codelineno-74-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-74-25" name="__codelineno-74-25" href="#__codelineno-74-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-74-26" name="__codelineno-74-26" href="#__codelineno-74-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">size</span><span class="p">)</span>
<a id="__codelineno-74-27" name="__codelineno-74-27" href="#__codelineno-74-27"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">IndexOutOfBoundsException</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">);</span>
<a id="__codelineno-74-28" name="__codelineno-74-28" href="#__codelineno-74-28"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">arr</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="p">;</span>
@@ -4631,13 +4631,13 @@
<a id="__codelineno-74-72" name="__codelineno-74-72" href="#__codelineno-74-72"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-74-73" name="__codelineno-74-73" href="#__codelineno-74-73"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-74-74" name="__codelineno-74-74" href="#__codelineno-74-74"></a><span class="w"> </span><span class="n">size</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-74-75" name="__codelineno-74-75" href="#__codelineno-74-75"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-74-75" name="__codelineno-74-75" href="#__codelineno-74-75"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-74-76" name="__codelineno-74-76" href="#__codelineno-74-76"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-74-77" name="__codelineno-74-77" href="#__codelineno-74-77"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-74-78" name="__codelineno-74-78" href="#__codelineno-74-78"></a>
<a id="__codelineno-74-79" name="__codelineno-74-79" href="#__codelineno-74-79"></a><span class="w"> </span><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-74-80" name="__codelineno-74-80" href="#__codelineno-74-80"></a><span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">extendCapacity</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-74-81" name="__codelineno-74-81" href="#__codelineno-74-81"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-74-81" name="__codelineno-74-81" href="#__codelineno-74-81"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-74-82" name="__codelineno-74-82" href="#__codelineno-74-82"></a><span class="w"> </span><span class="n">arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Arrays</span><span class="p">.</span><span class="na">copyOf</span><span class="p">(</span><span class="n">arr</span><span class="p">,</span><span class="w"> </span><span class="n">capacity</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">extendRatio</span><span class="p">);</span>
<a id="__codelineno-74-83" name="__codelineno-74-83" href="#__codelineno-74-83"></a><span class="w"> </span><span class="c1">// 更新列表容量</span>
<a id="__codelineno-74-84" name="__codelineno-74-84" href="#__codelineno-74-84"></a><span class="w"> </span><span class="n">capacity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">arr</span><span class="p">.</span><span class="na">length</span><span class="p">;</span>
@@ -4681,7 +4681,7 @@
<a id="__codelineno-75-22" name="__codelineno-75-22" href="#__codelineno-75-22"></a>
<a id="__codelineno-75-23" name="__codelineno-75-23" href="#__codelineno-75-23"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-75-24" name="__codelineno-75-24" href="#__codelineno-75-24"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">Get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-75-25" name="__codelineno-75-25" href="#__codelineno-75-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-75-25" name="__codelineno-75-25" href="#__codelineno-75-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-75-26" name="__codelineno-75-26" href="#__codelineno-75-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="m">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">arrSize</span><span class="p">)</span>
<a id="__codelineno-75-27" name="__codelineno-75-27" href="#__codelineno-75-27"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="nf">IndexOutOfRangeException</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">);</span>
<a id="__codelineno-75-28" name="__codelineno-75-28" href="#__codelineno-75-28"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">arr</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
@@ -4731,13 +4731,13 @@
<a id="__codelineno-75-72" name="__codelineno-75-72" href="#__codelineno-75-72"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-75-73" name="__codelineno-75-73" href="#__codelineno-75-73"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-75-74" name="__codelineno-75-74" href="#__codelineno-75-74"></a><span class="w"> </span><span class="n">arrSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-75-75" name="__codelineno-75-75" href="#__codelineno-75-75"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-75-75" name="__codelineno-75-75" href="#__codelineno-75-75"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-75-76" name="__codelineno-75-76" href="#__codelineno-75-76"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-75-77" name="__codelineno-75-77" href="#__codelineno-75-77"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-75-78" name="__codelineno-75-78" href="#__codelineno-75-78"></a>
<a id="__codelineno-75-79" name="__codelineno-75-79" href="#__codelineno-75-79"></a><span class="w"> </span><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-75-80" name="__codelineno-75-80" href="#__codelineno-75-80"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">ExtendCapacity</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-75-81" name="__codelineno-75-81" href="#__codelineno-75-81"></a><span class="w"> </span><span class="c1">// 新建一个长度为 arrCapacity * extendRatio 的数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-75-81" name="__codelineno-75-81" href="#__codelineno-75-81"></a><span class="w"> </span><span class="c1">// 新建一个长度为 arrCapacity * extendRatio 的数组,并将原数组复制到新数组</span>
<a id="__codelineno-75-82" name="__codelineno-75-82" href="#__codelineno-75-82"></a><span class="w"> </span><span class="n">Array</span><span class="p">.</span><span class="n">Resize</span><span class="p">(</span><span class="k">ref</span><span class="w"> </span><span class="n">arr</span><span class="p">,</span><span class="w"> </span><span class="n">arrCapacity</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">extendRatio</span><span class="p">);</span>
<a id="__codelineno-75-83" name="__codelineno-75-83" href="#__codelineno-75-83"></a><span class="w"> </span><span class="c1">// 更新列表容量</span>
<a id="__codelineno-75-84" name="__codelineno-75-84" href="#__codelineno-75-84"></a><span class="w"> </span><span class="n">arrCapacity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">arr</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span>
@@ -4786,7 +4786,7 @@
<a id="__codelineno-76-28" name="__codelineno-76-28" href="#__codelineno-76-28"></a>
<a id="__codelineno-76-29" name="__codelineno-76-29" href="#__codelineno-76-29"></a><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-76-30" name="__codelineno-76-30" href="#__codelineno-76-30"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="o">*</span><span class="nx">myList</span><span class="p">)</span><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">index</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-76-31" name="__codelineno-76-31" href="#__codelineno-76-31"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-76-31" name="__codelineno-76-31" href="#__codelineno-76-31"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-76-32" name="__codelineno-76-32" href="#__codelineno-76-32"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">arrSize</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-76-33" name="__codelineno-76-33" href="#__codelineno-76-33"></a><span class="w"> </span><span class="nb">panic</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">)</span>
<a id="__codelineno-76-34" name="__codelineno-76-34" href="#__codelineno-76-34"></a><span class="w"> </span><span class="p">}</span>
@@ -4842,13 +4842,13 @@
<a id="__codelineno-76-84" name="__codelineno-76-84" href="#__codelineno-76-84"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-76-85" name="__codelineno-76-85" href="#__codelineno-76-85"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-76-86" name="__codelineno-76-86" href="#__codelineno-76-86"></a><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">arrSize</span><span class="o">--</span>
<a id="__codelineno-76-87" name="__codelineno-76-87" href="#__codelineno-76-87"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-76-87" name="__codelineno-76-87" href="#__codelineno-76-87"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-76-88" name="__codelineno-76-88" href="#__codelineno-76-88"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span>
<a id="__codelineno-76-89" name="__codelineno-76-89" href="#__codelineno-76-89"></a><span class="p">}</span>
<a id="__codelineno-76-90" name="__codelineno-76-90" href="#__codelineno-76-90"></a>
<a id="__codelineno-76-91" name="__codelineno-76-91" href="#__codelineno-76-91"></a><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-76-92" name="__codelineno-76-92" href="#__codelineno-76-92"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="o">*</span><span class="nx">myList</span><span class="p">)</span><span class="w"> </span><span class="nx">extendCapacity</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-76-93" name="__codelineno-76-93" href="#__codelineno-76-93"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-76-93" name="__codelineno-76-93" href="#__codelineno-76-93"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-76-94" name="__codelineno-76-94" href="#__codelineno-76-94"></a><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">arr</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">arr</span><span class="p">,</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">arrCapacity</span><span class="o">*</span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">extendRatio</span><span class="o">-</span><span class="mi">1</span><span class="p">))</span><span class="o">...</span><span class="p">)</span>
<a id="__codelineno-76-95" name="__codelineno-76-95" href="#__codelineno-76-95"></a><span class="w"> </span><span class="c1">// 更新列表容量</span>
<a id="__codelineno-76-96" name="__codelineno-76-96" href="#__codelineno-76-96"></a><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">arrCapacity</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">len</span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">arr</span><span class="p">)</span>
@@ -4943,13 +4943,13 @@
<a id="__codelineno-77-79" name="__codelineno-77-79" href="#__codelineno-77-79"></a> <span class="p">}</span>
<a id="__codelineno-77-80" name="__codelineno-77-80" href="#__codelineno-77-80"></a> <span class="c1">// 更新元素数量</span>
<a id="__codelineno-77-81" name="__codelineno-77-81" href="#__codelineno-77-81"></a> <span class="n">_size</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-77-82" name="__codelineno-77-82" href="#__codelineno-77-82"></a> <span class="c1">// 返回被删除元素</span>
<a id="__codelineno-77-82" name="__codelineno-77-82" href="#__codelineno-77-82"></a> <span class="c1">// 返回被删除元素</span>
<a id="__codelineno-77-83" name="__codelineno-77-83" href="#__codelineno-77-83"></a> <span class="k">return</span> <span class="n">num</span>
<a id="__codelineno-77-84" name="__codelineno-77-84" href="#__codelineno-77-84"></a> <span class="p">}</span>
<a id="__codelineno-77-85" name="__codelineno-77-85" href="#__codelineno-77-85"></a>
<a id="__codelineno-77-86" name="__codelineno-77-86" href="#__codelineno-77-86"></a> <span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-77-87" name="__codelineno-77-87" href="#__codelineno-77-87"></a> <span class="kd">func</span> <span class="nf">extendCapacity</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-77-88" name="__codelineno-77-88" href="#__codelineno-77-88"></a> <span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-77-88" name="__codelineno-77-88" href="#__codelineno-77-88"></a> <span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-77-89" name="__codelineno-77-89" href="#__codelineno-77-89"></a> <span class="n">arr</span> <span class="p">=</span> <span class="n">arr</span> <span class="o">+</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="n">_capacity</span> <span class="o">*</span> <span class="p">(</span><span class="n">extendRatio</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span>
<a id="__codelineno-77-90" name="__codelineno-77-90" href="#__codelineno-77-90"></a> <span class="c1">// 更新列表容量</span>
<a id="__codelineno-77-91" name="__codelineno-77-91" href="#__codelineno-77-91"></a> <span class="n">_capacity</span> <span class="p">=</span> <span class="n">arr</span><span class="p">.</span><span class="bp">count</span>
@@ -4991,7 +4991,7 @@
<a id="__codelineno-78-22" name="__codelineno-78-22" href="#__codelineno-78-22"></a>
<a id="__codelineno-78-23" name="__codelineno-78-23" href="#__codelineno-78-23"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-78-24" name="__codelineno-78-24" href="#__codelineno-78-24"></a><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-25" name="__codelineno-78-25" href="#__codelineno-78-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-78-25" name="__codelineno-78-25" href="#__codelineno-78-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-78-26" name="__codelineno-78-26" href="#__codelineno-78-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">size</span><span class="p">)</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;索引越界&#39;</span><span class="p">);</span>
<a id="__codelineno-78-27" name="__codelineno-78-27" href="#__codelineno-78-27"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">arr</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-78-28" name="__codelineno-78-28" href="#__codelineno-78-28"></a><span class="w"> </span><span class="p">}</span>
@@ -5039,13 +5039,13 @@
<a id="__codelineno-78-70" name="__codelineno-78-70" href="#__codelineno-78-70"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-78-71" name="__codelineno-78-71" href="#__codelineno-78-71"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-78-72" name="__codelineno-78-72" href="#__codelineno-78-72"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">size</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-78-73" name="__codelineno-78-73" href="#__codelineno-78-73"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-78-73" name="__codelineno-78-73" href="#__codelineno-78-73"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-78-74" name="__codelineno-78-74" href="#__codelineno-78-74"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
<a id="__codelineno-78-75" name="__codelineno-78-75" href="#__codelineno-78-75"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-78-76" name="__codelineno-78-76" href="#__codelineno-78-76"></a>
<a id="__codelineno-78-77" name="__codelineno-78-77" href="#__codelineno-78-77"></a><span class="w"> </span><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-78-78" name="__codelineno-78-78" href="#__codelineno-78-78"></a><span class="w"> </span><span class="nx">extendCapacity</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-79" name="__codelineno-78-79" href="#__codelineno-78-79"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-78-79" name="__codelineno-78-79" href="#__codelineno-78-79"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extendRatio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-78-80" name="__codelineno-78-80" href="#__codelineno-78-80"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">arr</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span>
<a id="__codelineno-78-81" name="__codelineno-78-81" href="#__codelineno-78-81"></a><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">extendRatio</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">))</span>
<a id="__codelineno-78-82" name="__codelineno-78-82" href="#__codelineno-78-82"></a><span class="w"> </span><span class="p">);</span>
@@ -5091,7 +5091,7 @@
<a id="__codelineno-79-22" name="__codelineno-79-22" href="#__codelineno-79-22"></a>
<a id="__codelineno-79-23" name="__codelineno-79-23" href="#__codelineno-79-23"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-79-24" name="__codelineno-79-24" href="#__codelineno-79-24"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">index</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-79-25" name="__codelineno-79-25" href="#__codelineno-79-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-79-25" name="__codelineno-79-25" href="#__codelineno-79-25"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-79-26" name="__codelineno-79-26" href="#__codelineno-79-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_size</span><span class="p">)</span><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">&#39;索引越界&#39;</span><span class="p">);</span>
<a id="__codelineno-79-27" name="__codelineno-79-27" href="#__codelineno-79-27"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">arr</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-79-28" name="__codelineno-79-28" href="#__codelineno-79-28"></a><span class="w"> </span><span class="p">}</span>
@@ -5137,13 +5137,13 @@
<a id="__codelineno-79-68" name="__codelineno-79-68" href="#__codelineno-79-68"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-79-69" name="__codelineno-79-69" href="#__codelineno-79-69"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-79-70" name="__codelineno-79-70" href="#__codelineno-79-70"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">_size</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-79-71" name="__codelineno-79-71" href="#__codelineno-79-71"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-79-71" name="__codelineno-79-71" href="#__codelineno-79-71"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-79-72" name="__codelineno-79-72" href="#__codelineno-79-72"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
<a id="__codelineno-79-73" name="__codelineno-79-73" href="#__codelineno-79-73"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-79-74" name="__codelineno-79-74" href="#__codelineno-79-74"></a>
<a id="__codelineno-79-75" name="__codelineno-79-75" href="#__codelineno-79-75"></a><span class="w"> </span><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-79-76" name="__codelineno-79-76" href="#__codelineno-79-76"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="nx">extendCapacity</span><span class="p">()</span><span class="o">:</span><span class="w"> </span><span class="ow">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-79-77" name="__codelineno-79-77" href="#__codelineno-79-77"></a><span class="w"> </span><span class="c1">// 新建一个长度为 size 的数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-79-77" name="__codelineno-79-77" href="#__codelineno-79-77"></a><span class="w"> </span><span class="c1">// 新建一个长度为 size 的数组,并将原数组复制到新数组</span>
<a id="__codelineno-79-78" name="__codelineno-79-78" href="#__codelineno-79-78"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">arr</span><span class="p">.</span><span class="nx">concat</span><span class="p">(</span>
<a id="__codelineno-79-79" name="__codelineno-79-79" href="#__codelineno-79-79"></a><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">extendRatio</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">))</span>
<a id="__codelineno-79-80" name="__codelineno-79-80" href="#__codelineno-79-80"></a><span class="w"> </span><span class="p">);</span>
@@ -5228,7 +5228,7 @@
<a id="__codelineno-80-61" name="__codelineno-80-61" href="#__codelineno-80-61"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-80-62" name="__codelineno-80-62" href="#__codelineno-80-62"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-80-63" name="__codelineno-80-63" href="#__codelineno-80-63"></a><span class="w"> </span><span class="n">_size</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-80-64" name="__codelineno-80-64" href="#__codelineno-80-64"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-80-64" name="__codelineno-80-64" href="#__codelineno-80-64"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-80-65" name="__codelineno-80-65" href="#__codelineno-80-65"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">_num</span><span class="p">;</span>
<a id="__codelineno-80-66" name="__codelineno-80-66" href="#__codelineno-80-66"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-80-67" name="__codelineno-80-67" href="#__codelineno-80-67"></a>
@@ -5236,7 +5236,7 @@
<a id="__codelineno-80-69" name="__codelineno-80-69" href="#__codelineno-80-69"></a><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">extendCapacity</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-80-70" name="__codelineno-80-70" href="#__codelineno-80-70"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 _extendRatio 倍的新数组</span>
<a id="__codelineno-80-71" name="__codelineno-80-71" href="#__codelineno-80-71"></a><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">_newNums</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="n">_capacity</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">_extendRatio</span><span class="p">,</span><span class="w"> </span><span class="m">0</span><span class="p">);</span>
<a id="__codelineno-80-72" name="__codelineno-80-72" href="#__codelineno-80-72"></a><span class="w"> </span><span class="c1">// 将原数组拷贝到新数组</span>
<a id="__codelineno-80-72" name="__codelineno-80-72" href="#__codelineno-80-72"></a><span class="w"> </span><span class="c1">// 将原数组复制到新数组</span>
<a id="__codelineno-80-73" name="__codelineno-80-73" href="#__codelineno-80-73"></a><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">copyRange</span><span class="p">(</span><span class="n">_newNums</span><span class="p">,</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">_arr</span><span class="p">);</span>
<a id="__codelineno-80-74" name="__codelineno-80-74" href="#__codelineno-80-74"></a><span class="w"> </span><span class="c1">// 更新 _arr 的引用</span>
<a id="__codelineno-80-75" name="__codelineno-80-75" href="#__codelineno-80-75"></a><span class="w"> </span><span class="n">_arr</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_newNums</span><span class="p">;</span>
@@ -5291,7 +5291,7 @@
<a id="__codelineno-81-33" name="__codelineno-81-33" href="#__codelineno-81-33"></a>
<a id="__codelineno-81-34" name="__codelineno-81-34" href="#__codelineno-81-34"></a><span class="w"> </span><span class="cm">/* 访问元素 */</span>
<a id="__codelineno-81-35" name="__codelineno-81-35" href="#__codelineno-81-35"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">get</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">index</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span>
<a id="__codelineno-81-36" name="__codelineno-81-36" href="#__codelineno-81-36"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-81-36" name="__codelineno-81-36" href="#__codelineno-81-36"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-81-37" name="__codelineno-81-37" href="#__codelineno-81-37"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">size</span><span class="w"> </span><span class="p">{</span><span class="fm">panic!</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">)};</span>
<a id="__codelineno-81-38" name="__codelineno-81-38" href="#__codelineno-81-38"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">arr</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-81-39" name="__codelineno-81-39" href="#__codelineno-81-39"></a><span class="w"> </span><span class="p">}</span>
@@ -5339,13 +5339,13 @@
<a id="__codelineno-81-81" name="__codelineno-81-81" href="#__codelineno-81-81"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-81-82" name="__codelineno-81-82" href="#__codelineno-81-82"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-81-83" name="__codelineno-81-83" href="#__codelineno-81-83"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">size</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-81-84" name="__codelineno-81-84" href="#__codelineno-81-84"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-81-84" name="__codelineno-81-84" href="#__codelineno-81-84"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-81-85" name="__codelineno-81-85" href="#__codelineno-81-85"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-81-86" name="__codelineno-81-86" href="#__codelineno-81-86"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-81-87" name="__codelineno-81-87" href="#__codelineno-81-87"></a>
<a id="__codelineno-81-88" name="__codelineno-81-88" href="#__codelineno-81-88"></a><span class="w"> </span><span class="cm">/* 列表扩容 */</span>
<a id="__codelineno-81-89" name="__codelineno-81-89" href="#__codelineno-81-89"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">extend_capacity</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-81-90" name="__codelineno-81-90" href="#__codelineno-81-90"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-81-90" name="__codelineno-81-90" href="#__codelineno-81-90"></a><span class="w"> </span><span class="c1">// 新建一个长度为原数组 extend_ratio 倍的新数组,并将原数组复制到新数组</span>
<a id="__codelineno-81-91" name="__codelineno-81-91" href="#__codelineno-81-91"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">new_capacity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">capacity</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">extend_ratio</span><span class="p">;</span>
<a id="__codelineno-81-92" name="__codelineno-81-92" href="#__codelineno-81-92"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">arr</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">new_capacity</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<a id="__codelineno-81-93" name="__codelineno-81-93" href="#__codelineno-81-93"></a><span class="w"> </span><span class="c1">// 更新列表容量</span>
@@ -5512,14 +5512,14 @@
<a id="__codelineno-83-38" name="__codelineno-83-38" href="#__codelineno-83-38"></a>
<a id="__codelineno-83-39" name="__codelineno-83-39" href="#__codelineno-83-39"></a><span class="w"> </span><span class="c1">// 访问元素</span>
<a id="__codelineno-83-40" name="__codelineno-83-40" href="#__codelineno-83-40"></a><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">get</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">,</span><span class="w"> </span><span class="n">index</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-83-41" name="__codelineno-83-41" href="#__codelineno-83-41"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-83-41" name="__codelineno-83-41" href="#__codelineno-83-41"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-83-42" name="__codelineno-83-42" href="#__codelineno-83-42"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">size</span><span class="p">())</span><span class="w"> </span><span class="nb">@panic</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">);</span>
<a id="__codelineno-83-43" name="__codelineno-83-43" href="#__codelineno-83-43"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">arr</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-83-44" name="__codelineno-83-44" href="#__codelineno-83-44"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span>
<a id="__codelineno-83-45" name="__codelineno-83-45" href="#__codelineno-83-45"></a>
<a id="__codelineno-83-46" name="__codelineno-83-46" href="#__codelineno-83-46"></a><span class="w"> </span><span class="c1">// 更新元素</span>
<a id="__codelineno-83-47" name="__codelineno-83-47" href="#__codelineno-83-47"></a><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">set</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">,</span><span class="w"> </span><span class="n">index</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">num</span><span class="o">:</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-83-48" name="__codelineno-83-48" href="#__codelineno-83-48"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-83-48" name="__codelineno-83-48" href="#__codelineno-83-48"></a><span class="w"> </span><span class="c1">// 索引如果越界则抛出异常,下同</span>
<a id="__codelineno-83-49" name="__codelineno-83-49" href="#__codelineno-83-49"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="mi">0</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">&gt;=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">size</span><span class="p">())</span><span class="w"> </span><span class="nb">@panic</span><span class="p">(</span><span class="s">&quot;索引越界&quot;</span><span class="p">);</span>
<a id="__codelineno-83-50" name="__codelineno-83-50" href="#__codelineno-83-50"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">arr</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-83-51" name="__codelineno-83-51" href="#__codelineno-83-51"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span>
@@ -5559,13 +5559,13 @@
<a id="__codelineno-83-85" name="__codelineno-83-85" href="#__codelineno-83-85"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-83-86" name="__codelineno-83-86" href="#__codelineno-83-86"></a><span class="w"> </span><span class="c1">// 更新元素数量</span>
<a id="__codelineno-83-87" name="__codelineno-83-87" href="#__codelineno-83-87"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">numSize</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-83-88" name="__codelineno-83-88" href="#__codelineno-83-88"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-83-88" name="__codelineno-83-88" href="#__codelineno-83-88"></a><span class="w"> </span><span class="c1">// 返回被删除元素</span>
<a id="__codelineno-83-89" name="__codelineno-83-89" href="#__codelineno-83-89"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-83-90" name="__codelineno-83-90" href="#__codelineno-83-90"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-83-91" name="__codelineno-83-91" href="#__codelineno-83-91"></a>
<a id="__codelineno-83-92" name="__codelineno-83-92" href="#__codelineno-83-92"></a><span class="w"> </span><span class="c1">// 列表扩容</span>
<a id="__codelineno-83-93" name="__codelineno-83-93" href="#__codelineno-83-93"></a><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">extendCapacity</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-83-94" name="__codelineno-83-94" href="#__codelineno-83-94"></a><span class="w"> </span><span class="c1">// 新建一个长度为 size * extendRatio 的数组,并将原数组拷贝到新数组</span>
<a id="__codelineno-83-94" name="__codelineno-83-94" href="#__codelineno-83-94"></a><span class="w"> </span><span class="c1">// 新建一个长度为 size * extendRatio 的数组,并将原数组复制到新数组</span>
<a id="__codelineno-83-95" name="__codelineno-83-95" href="#__codelineno-83-95"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">newCapacity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">capacity</span><span class="p">()</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">extendRatio</span><span class="p">;</span>
<a id="__codelineno-83-96" name="__codelineno-83-96" href="#__codelineno-83-96"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">extend</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mem_allocator</span><span class="p">.</span><span class="n">alloc</span><span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">newCapacity</span><span class="p">);</span>
<a id="__codelineno-83-97" name="__codelineno-83-97" href="#__codelineno-83-97"></a><span class="w"> </span><span class="nb">@memset</span><span class="p">(</span><span class="n">extend</span><span class="p">,</span><span class="w"> </span><span class="nb">@as</span><span class="p">(</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">));</span>
@@ -1796,7 +1796,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3519,9 +3519,8 @@
<ul>
<li>数组和链表是两种基本的数据结构,分别代表数据在计算机内存中的两种存储方式:连续空间存储和分散空间存储。两者的特点呈现出互补的特性。</li>
<li>数组支持随机访问、占用内存较少;但插入和删除元素效率低,且初始化后长度不可变。</li>
<li>链表通过更改引用(指针)实现高效的节点插入与删除,且可以灵活调整长度;但节点访问效率低、占用内存较多。</li>
<li>常见的链表类型包括单向链表、环形链表、双向链表,它们分别具有各自的应用场景</li>
<li>列表是一种支持增删查改的元素有序集合,通常基于动态数组实现,其保留了数组的优势,同时可以灵活调整长度。</li>
<li>链表通过更改引用(指针)实现高效的节点插入与删除,且可以灵活调整长度;但节点访问效率低、占用内存较多。常见的链表类型包括单向链表、环形链表、双向链表。</li>
<li>列表是一种支持增删查改的元素有序集合,通常基于动态数组实现,它保留了数组的优势,同时可以灵活调整长度</li>
<li>列表的出现大幅地提高了数组的实用性,但可能导致部分内存空间浪费。</li>
<li>程序运行时,数据主要存储在内存中。数组可提供更高的内存空间效率,而链表则在内存使用上更加灵活。</li>
<li>缓存通过缓存行、预取机制以及空间局部性和时间局部性等数据加载机制,为 CPU 提供快速数据访问,显著提升程序的执行效率。</li>
@@ -3539,13 +3538,13 @@
</div>
<div class="admonition question">
<p class="admonition-title">为什么数组要求相同类型的元素,而在链表中却没有强调同类型呢?</p>
<p>链表由节点组成,节点之间通过引用(指针)连接,各个节点可以存储不同类型的数据,例如 int、double、string、object 等。</p>
<p>相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,数组同时包含 int 和 long 两种类型,单个元素分别占用 4 bytes 和 8 bytes ,此时就不能用以下公式计算偏移量了,因为数组中包含了两种长度的元素</p>
<p>链表由节点组成,节点之间通过引用(指针)连接,各个节点可以存储不同类型的数据,例如 <code>int</code><code>double</code><code>string</code><code>object</code> 等。</p>
<p>相对地,数组元素则必须是相同类型的,这样才能通过计算偏移量来获取对应元素位置。例如,数组同时包含 <code>int</code><code>long</code> 两种类型,单个元素分别占用 4 字节 和 8 字节 ,此时就不能用以下公式计算偏移量了,因为数组中包含了两种“元素长度”</p>
<div class="highlight"><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># 元素内存地址 = 数组内存地址 + 元素长度 * 元素索引</span>
</code></pre></div>
</div>
<div class="admonition question">
<p class="admonition-title">删除节点后,是否需要把 <code>P.next</code> 设为 <span class="arithmatex">\(\text{None}\)</span> 呢?</p>
<p class="admonition-title">删除节点后,是否需要把 <code>P.next</code> 设为 <code>None</code> 呢?</p>
<p>不修改 <code>P.next</code> 也可以。从该链表的角度看,从头节点遍历到尾节点已经不会遇到 <code>P</code> 了。这意味着节点 <code>P</code> 已经从链表中删除了,此时节点 <code>P</code> 指向哪里都不会对该链表产生影响。</p>
<p>从垃圾回收的角度看,对于 Java、Python、Go 等拥有自动垃圾回收机制的语言来说,节点 <code>P</code> 是否被回收取决于是否仍存在指向它的引用,而不是 <code>P.next</code> 的值。在 C 和 C++ 等语言中,我们需要手动释放节点内存。</p>
</div>
@@ -3557,7 +3556,7 @@
<p class="admonition-title">图“链表定义与存储方式”中,浅蓝色的存储节点指针是占用一块内存地址吗?还是和节点值各占一半呢?</p>
<p>该示意图只是定性表示,定量表示需要根据具体情况进行分析。</p>
<ul>
<li>不同类型的节点值占用的空间是不同的,比如 int、long、double 和实例对象等。</li>
<li>不同类型的节点值占用的空间是不同的,比如 <code>int</code><code>long</code><code>double</code> 和实例对象等。</li>
<li>指针变量占用的内存空间大小根据所使用的操作系统及编译环境而定,大多为 8 字节或 4 字节。</li>
</ul>
</div>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3541,7 +3541,7 @@
<p><a class="glightbox" href="../n_queens_problem.assets/solution_4_queens.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="4 皇后问题的解" class="animation-figure" src="../n_queens_problem.assets/solution_4_queens.png" /></a></p>
<p align="center"> 图 13-15 &nbsp; 4 皇后问题的解 </p>
<p>图 13-16 展示了本题的三个约束条件:<strong>多个皇后不能在同一行、同一列、同一对角线</strong>。值得注意的是,对角线分为主对角线 <code>\</code> 和次对角线 <code>/</code> 两种。</p>
<p>图 13-16 展示了本题的三个约束条件:<strong>多个皇后不能在同一行、同一列、同一对角线</strong>。值得注意的是,对角线分为主对角线 <code>\</code> 和次对角线 <code>/</code> 两种。</p>
<p><a class="glightbox" href="../n_queens_problem.assets/n_queens_constraints.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="n 皇后问题的约束条件" class="animation-figure" src="../n_queens_problem.assets/n_queens_constraints.png" /></a></p>
<p align="center"> 图 13-16 &nbsp; n 皇后问题的约束条件 </p>
@@ -3582,10 +3582,10 @@
<a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> <span class="k">return</span>
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> <span class="c1"># 遍历所有列</span>
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> <span class="k">for</span> <span class="n">col</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="c1"># 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> <span class="c1"># 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a> <span class="n">diag1</span> <span class="o">=</span> <span class="n">row</span> <span class="o">-</span> <span class="n">col</span> <span class="o">+</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> <span class="n">diag2</span> <span class="o">=</span> <span class="n">row</span> <span class="o">+</span> <span class="n">col</span>
<a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> <span class="c1"># 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a> <span class="c1"># 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">]:</span>
<a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a> <span class="c1"># 尝试:将皇后放置在该格子</span>
<a id="__codelineno-0-23" name="__codelineno-0-23" href="#__codelineno-0-23"></a> <span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;Q&quot;</span>
@@ -3602,7 +3602,7 @@
<a id="__codelineno-0-34" name="__codelineno-0-34" href="#__codelineno-0-34"></a> <span class="n">state</span> <span class="o">=</span> <span class="p">[[</span><span class="s2">&quot;#&quot;</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">)]</span> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">)]</span>
<a id="__codelineno-0-35" name="__codelineno-0-35" href="#__codelineno-0-35"></a> <span class="n">cols</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">*</span> <span class="n">n</span> <span class="c1"># 记录列是否有皇后</span>
<a id="__codelineno-0-36" name="__codelineno-0-36" href="#__codelineno-0-36"></a> <span class="n">diags1</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># 记录主对角线上是否有皇后</span>
<a id="__codelineno-0-37" name="__codelineno-0-37" href="#__codelineno-0-37"></a> <span class="n">diags2</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># 记录对角线上是否有皇后</span>
<a id="__codelineno-0-37" name="__codelineno-0-37" href="#__codelineno-0-37"></a> <span class="n">diags2</span> <span class="o">=</span> <span class="p">[</span><span class="kc">False</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># 记录对角线上是否有皇后</span>
<a id="__codelineno-0-38" name="__codelineno-0-38" href="#__codelineno-0-38"></a> <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
<a id="__codelineno-0-39" name="__codelineno-0-39" href="#__codelineno-0-39"></a> <span class="n">backtrack</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">n</span><span class="p">,</span> <span class="n">state</span><span class="p">,</span> <span class="n">res</span><span class="p">,</span> <span class="n">cols</span><span class="p">,</span> <span class="n">diags1</span><span class="p">,</span> <span class="n">diags2</span><span class="p">)</span>
<a id="__codelineno-0-40" name="__codelineno-0-40" href="#__codelineno-0-40"></a>
@@ -3620,10 +3620,10 @@
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a><span class="w"> </span><span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;Q&quot;</span><span class="p">;</span>
@@ -3643,7 +3643,7 @@
<a id="__codelineno-1-31" name="__codelineno-1-31" href="#__codelineno-1-31"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">state</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;#&quot;</span><span class="p">));</span>
<a id="__codelineno-1-32" name="__codelineno-1-32" href="#__codelineno-1-32"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">cols</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-1-33" name="__codelineno-1-33" href="#__codelineno-1-33"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags1</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-1-34" name="__codelineno-1-34" href="#__codelineno-1-34"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags2</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-1-34" name="__codelineno-1-34" href="#__codelineno-1-34"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags2</span><span class="p">(</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="nb">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-1-35" name="__codelineno-1-35" href="#__codelineno-1-35"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">string</span><span class="o">&gt;&gt;&gt;</span><span class="w"> </span><span class="n">res</span><span class="p">;</span>
<a id="__codelineno-1-36" name="__codelineno-1-36" href="#__codelineno-1-36"></a>
<a id="__codelineno-1-37" name="__codelineno-1-37" href="#__codelineno-1-37"></a><span class="w"> </span><span class="n">backtrack</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">state</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">cols</span><span class="p">,</span><span class="w"> </span><span class="n">diags1</span><span class="p">,</span><span class="w"> </span><span class="n">diags2</span><span class="p">);</span>
@@ -3667,10 +3667,10 @@
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">cols</span><span class="o">[</span><span class="n">col</span><span class="o">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="o">[</span><span class="n">diag1</span><span class="o">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="o">[</span><span class="n">diag2</span><span class="o">]</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-2-21" name="__codelineno-2-21" href="#__codelineno-2-21"></a><span class="w"> </span><span class="n">state</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">row</span><span class="p">).</span><span class="na">set</span><span class="p">(</span><span class="n">col</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;Q&quot;</span><span class="p">);</span>
@@ -3697,7 +3697,7 @@
<a id="__codelineno-2-42" name="__codelineno-2-42" href="#__codelineno-2-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-2-43" name="__codelineno-2-43" href="#__codelineno-2-43"></a><span class="w"> </span><span class="kt">boolean</span><span class="o">[]</span><span class="w"> </span><span class="n">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">boolean</span><span class="o">[</span><span class="n">n</span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-2-44" name="__codelineno-2-44" href="#__codelineno-2-44"></a><span class="w"> </span><span class="kt">boolean</span><span class="o">[]</span><span class="w"> </span><span class="n">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">boolean</span><span class="o">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-2-45" name="__codelineno-2-45" href="#__codelineno-2-45"></a><span class="w"> </span><span class="kt">boolean</span><span class="o">[]</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">boolean</span><span class="o">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-2-45" name="__codelineno-2-45" href="#__codelineno-2-45"></a><span class="w"> </span><span class="kt">boolean</span><span class="o">[]</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">boolean</span><span class="o">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-2-46" name="__codelineno-2-46" href="#__codelineno-2-46"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">String</span><span class="o">&gt;&gt;&gt;</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ArrayList</span><span class="o">&lt;&gt;</span><span class="p">();</span>
<a id="__codelineno-2-47" name="__codelineno-2-47" href="#__codelineno-2-47"></a>
<a id="__codelineno-2-48" name="__codelineno-2-48" href="#__codelineno-2-48"></a><span class="w"> </span><span class="n">backtrack</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">state</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">cols</span><span class="p">,</span><span class="w"> </span><span class="n">diags1</span><span class="p">,</span><span class="w"> </span><span class="n">diags2</span><span class="p">);</span>
@@ -3721,10 +3721,10 @@
<a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-15" name="__codelineno-3-15" href="#__codelineno-3-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-3-15" name="__codelineno-3-15" href="#__codelineno-3-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-3-16" name="__codelineno-3-16" href="#__codelineno-3-16"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-3-17" name="__codelineno-3-17" href="#__codelineno-3-17"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-3-18" name="__codelineno-3-18" href="#__codelineno-3-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-3-18" name="__codelineno-3-18" href="#__codelineno-3-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-3-19" name="__codelineno-3-19" href="#__codelineno-3-19"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-20" name="__codelineno-3-20" href="#__codelineno-3-20"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-3-21" name="__codelineno-3-21" href="#__codelineno-3-21"></a><span class="w"> </span><span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;Q&quot;</span><span class="p">;</span>
@@ -3751,7 +3751,7 @@
<a id="__codelineno-3-42" name="__codelineno-3-42" href="#__codelineno-3-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-3-43" name="__codelineno-3-43" href="#__codelineno-3-43"></a><span class="w"> </span><span class="kt">bool</span><span class="p">[]</span><span class="w"> </span><span class="n">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">bool</span><span class="p">[</span><span class="n">n</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-3-44" name="__codelineno-3-44" href="#__codelineno-3-44"></a><span class="w"> </span><span class="kt">bool</span><span class="p">[]</span><span class="w"> </span><span class="n">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">bool</span><span class="p">[</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-3-45" name="__codelineno-3-45" href="#__codelineno-3-45"></a><span class="w"> </span><span class="kt">bool</span><span class="p">[]</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">bool</span><span class="p">[</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-3-45" name="__codelineno-3-45" href="#__codelineno-3-45"></a><span class="w"> </span><span class="kt">bool</span><span class="p">[]</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">bool</span><span class="p">[</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-3-46" name="__codelineno-3-46" href="#__codelineno-3-46"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">string</span><span class="o">&gt;&gt;&gt;</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
<a id="__codelineno-3-47" name="__codelineno-3-47" href="#__codelineno-3-47"></a>
<a id="__codelineno-3-48" name="__codelineno-3-48" href="#__codelineno-3-48"></a><span class="w"> </span><span class="n">Backtrack</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">state</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">cols</span><span class="p">,</span><span class="w"> </span><span class="n">diags1</span><span class="p">,</span><span class="w"> </span><span class="n">diags2</span><span class="p">);</span>
@@ -3775,10 +3775,10 @@
<a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">n</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a><span class="w"> </span><span class="nx">diag1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span>
<a id="__codelineno-4-17" name="__codelineno-4-17" href="#__codelineno-4-17"></a><span class="w"> </span><span class="nx">diag2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">col</span>
<a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-4-19" name="__codelineno-4-19" href="#__codelineno-4-19"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">cols</span><span class="p">)[</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">diags1</span><span class="p">)[</span><span class="nx">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">diags2</span><span class="p">)[</span><span class="nx">diag2</span><span class="p">]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-20" name="__codelineno-4-20" href="#__codelineno-4-20"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-4-21" name="__codelineno-4-21" href="#__codelineno-4-21"></a><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="nx">state</span><span class="p">)[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&quot;Q&quot;</span>
@@ -3806,10 +3806,10 @@
<a id="__codelineno-4-43" name="__codelineno-4-43" href="#__codelineno-4-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-4-44" name="__codelineno-4-44" href="#__codelineno-4-44"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">n</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-4-47" name="__codelineno-4-47" href="#__codelineno-4-47"></a><span class="w"> </span><span class="nx">diag1</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span>
<a id="__codelineno-4-48" name="__codelineno-4-48" href="#__codelineno-4-48"></a><span class="w"> </span><span class="nx">diag2</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">col</span>
<a id="__codelineno-4-49" name="__codelineno-4-49" href="#__codelineno-4-49"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-4-49" name="__codelineno-4-49" href="#__codelineno-4-49"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-4-50" name="__codelineno-4-50" href="#__codelineno-4-50"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">cols</span><span class="p">)[</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">diags1</span><span class="p">)[</span><span class="nx">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="p">!(</span><span class="o">*</span><span class="nx">diags2</span><span class="p">)[</span><span class="nx">diag2</span><span class="p">]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-51" name="__codelineno-4-51" href="#__codelineno-4-51"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-4-52" name="__codelineno-4-52" href="#__codelineno-4-52"></a><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="nx">state</span><span class="p">)[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&quot;Q&quot;</span>
@@ -3853,10 +3853,10 @@
<a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> <span class="p">}</span>
<a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="c1">// 遍历所有列</span>
<a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> <span class="k">for</span> <span class="n">col</span> <span class="k">in</span> <span class="mi">0</span> <span class="p">..</span><span class="o">&lt;</span> <span class="n">n</span> <span class="p">{</span>
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="kd">let</span> <span class="nv">diag1</span> <span class="p">=</span> <span class="n">row</span> <span class="o">-</span> <span class="n">col</span> <span class="o">+</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="kd">let</span> <span class="nv">diag2</span> <span class="p">=</span> <span class="n">row</span> <span class="o">+</span> <span class="n">col</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="k">if</span> <span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">]</span> <span class="p">{</span>
<a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> <span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span> <span class="p">=</span> <span class="s">&quot;Q&quot;</span>
@@ -3880,7 +3880,7 @@
<a id="__codelineno-5-34" name="__codelineno-5-34" href="#__codelineno-5-34"></a> <span class="kd">var</span> <span class="nv">state</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="s">&quot;#&quot;</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="n">n</span><span class="p">),</span> <span class="bp">count</span><span class="p">:</span> <span class="n">n</span><span class="p">)</span>
<a id="__codelineno-5-35" name="__codelineno-5-35" href="#__codelineno-5-35"></a> <span class="kd">var</span> <span class="nv">cols</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="n">n</span><span class="p">)</span> <span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-5-36" name="__codelineno-5-36" href="#__codelineno-5-36"></a> <span class="kd">var</span> <span class="nv">diags1</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-5-37" name="__codelineno-5-37" href="#__codelineno-5-37"></a> <span class="kd">var</span> <span class="nv">diags2</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-5-37" name="__codelineno-5-37" href="#__codelineno-5-37"></a> <span class="kd">var</span> <span class="nv">diags2</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="kc">false</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-5-38" name="__codelineno-5-38" href="#__codelineno-5-38"></a> <span class="kd">var</span> <span class="nv">res</span><span class="p">:</span> <span class="p">[[[</span><span class="nb">String</span><span class="p">]]]</span> <span class="p">=</span> <span class="p">[]</span>
<a id="__codelineno-5-39" name="__codelineno-5-39" href="#__codelineno-5-39"></a>
<a id="__codelineno-5-40" name="__codelineno-5-40" href="#__codelineno-5-40"></a> <span class="n">backtrack</span><span class="p">(</span><span class="n">row</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">n</span><span class="p">:</span> <span class="n">n</span><span class="p">,</span> <span class="n">state</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">state</span><span class="p">,</span> <span class="n">res</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">res</span><span class="p">,</span> <span class="n">cols</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">cols</span><span class="p">,</span> <span class="n">diags1</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">diags1</span><span class="p">,</span> <span class="n">diags2</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">diags2</span><span class="p">)</span>
@@ -3899,10 +3899,10 @@
<a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">n</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">col</span><span class="p">;</span>
<a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-6-14" name="__codelineno-6-14" href="#__codelineno-6-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">cols</span><span class="p">[</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="nx">diags1</span><span class="p">[</span><span class="nx">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="nx">diags2</span><span class="p">[</span><span class="nx">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-15" name="__codelineno-6-15" href="#__codelineno-6-15"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-6-16" name="__codelineno-6-16" href="#__codelineno-6-16"></a><span class="w"> </span><span class="nx">state</span><span class="p">[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;Q&#39;</span><span class="p">;</span>
@@ -3922,7 +3922,7 @@
<a id="__codelineno-6-30" name="__codelineno-6-30" href="#__codelineno-6-30"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">.</span><span class="kr">from</span><span class="p">({</span><span class="w"> </span><span class="nx">length</span><span class="o">:</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="p">));</span>
<a id="__codelineno-6-31" name="__codelineno-6-31" href="#__codelineno-6-31"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-6-32" name="__codelineno-6-32" href="#__codelineno-6-32"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-6-33" name="__codelineno-6-33" href="#__codelineno-6-33"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-6-33" name="__codelineno-6-33" href="#__codelineno-6-33"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-6-34" name="__codelineno-6-34" href="#__codelineno-6-34"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
<a id="__codelineno-6-35" name="__codelineno-6-35" href="#__codelineno-6-35"></a>
<a id="__codelineno-6-36" name="__codelineno-6-36" href="#__codelineno-6-36"></a><span class="w"> </span><span class="nx">backtrack</span><span class="p">(</span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="p">,</span><span class="w"> </span><span class="nx">state</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">,</span><span class="w"> </span><span class="nx">cols</span><span class="p">,</span><span class="w"> </span><span class="nx">diags1</span><span class="p">,</span><span class="w"> </span><span class="nx">diags2</span><span class="p">);</span>
@@ -3948,10 +3948,10 @@
<a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">let</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">n</span><span class="p">;</span><span class="w"> </span><span class="nx">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-7-19" name="__codelineno-7-19" href="#__codelineno-7-19"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-7-20" name="__codelineno-7-20" href="#__codelineno-7-20"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">col</span><span class="p">;</span>
<a id="__codelineno-7-21" name="__codelineno-7-21" href="#__codelineno-7-21"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-7-21" name="__codelineno-7-21" href="#__codelineno-7-21"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-7-22" name="__codelineno-7-22" href="#__codelineno-7-22"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">cols</span><span class="p">[</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="nx">diags1</span><span class="p">[</span><span class="nx">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="nx">diags2</span><span class="p">[</span><span class="nx">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-23" name="__codelineno-7-23" href="#__codelineno-7-23"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-7-24" name="__codelineno-7-24" href="#__codelineno-7-24"></a><span class="w"> </span><span class="nx">state</span><span class="p">[</span><span class="nx">row</span><span class="p">][</span><span class="nx">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">&#39;Q&#39;</span><span class="p">;</span>
@@ -3971,7 +3971,7 @@
<a id="__codelineno-7-38" name="__codelineno-7-38" href="#__codelineno-7-38"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">.</span><span class="kr">from</span><span class="p">({</span><span class="w"> </span><span class="nx">length</span><span class="o">:</span><span class="w"> </span><span class="kt">n</span><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=&gt;</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="p">));</span>
<a id="__codelineno-7-39" name="__codelineno-7-39" href="#__codelineno-7-39"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">n</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-7-40" name="__codelineno-7-40" href="#__codelineno-7-40"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-7-41" name="__codelineno-7-41" href="#__codelineno-7-41"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-7-41" name="__codelineno-7-41" href="#__codelineno-7-41"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">fill</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-7-42" name="__codelineno-7-42" href="#__codelineno-7-42"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">res</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">[][][]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
<a id="__codelineno-7-43" name="__codelineno-7-43" href="#__codelineno-7-43"></a>
<a id="__codelineno-7-44" name="__codelineno-7-44" href="#__codelineno-7-44"></a><span class="w"> </span><span class="nx">backtrack</span><span class="p">(</span><span class="mf">0</span><span class="p">,</span><span class="w"> </span><span class="nx">n</span><span class="p">,</span><span class="w"> </span><span class="nx">state</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">,</span><span class="w"> </span><span class="nx">cols</span><span class="p">,</span><span class="w"> </span><span class="nx">diags1</span><span class="p">,</span><span class="w"> </span><span class="nx">diags2</span><span class="p">);</span>
@@ -4001,10 +4001,10 @@
<a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-8-23" name="__codelineno-8-23" href="#__codelineno-8-23"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-8-24" name="__codelineno-8-24" href="#__codelineno-8-24"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-8-25" name="__codelineno-8-25" href="#__codelineno-8-25"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-8-25" name="__codelineno-8-25" href="#__codelineno-8-25"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-8-26" name="__codelineno-8-26" href="#__codelineno-8-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-27" name="__codelineno-8-27" href="#__codelineno-8-27"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-8-28" name="__codelineno-8-28" href="#__codelineno-8-28"></a><span class="w"> </span><span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;Q&quot;</span><span class="p">;</span>
@@ -4028,7 +4028,7 @@
<a id="__codelineno-8-46" name="__codelineno-8-46" href="#__codelineno-8-46"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;&gt;</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">generate</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="s2">&quot;#&quot;</span><span class="p">));</span>
<a id="__codelineno-8-47" name="__codelineno-8-47" href="#__codelineno-8-47"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-8-48" name="__codelineno-8-48" href="#__codelineno-8-48"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-8-49" name="__codelineno-8-49" href="#__codelineno-8-49"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-8-49" name="__codelineno-8-49" href="#__codelineno-8-49"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="kt">bool</span><span class="o">&gt;</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="kc">false</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-8-50" name="__codelineno-8-50" href="#__codelineno-8-50"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">String</span><span class="o">&gt;&gt;&gt;</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
<a id="__codelineno-8-51" name="__codelineno-8-51" href="#__codelineno-8-51"></a>
<a id="__codelineno-8-52" name="__codelineno-8-52" href="#__codelineno-8-52"></a><span class="w"> </span><span class="n">backtrack</span><span class="p">(</span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="n">state</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">cols</span><span class="p">,</span><span class="w"> </span><span class="n">diags1</span><span class="p">,</span><span class="w"> </span><span class="n">diags2</span><span class="p">);</span>
@@ -4052,10 +4052,10 @@
<a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-13" name="__codelineno-9-13" href="#__codelineno-9-13"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-9-14" name="__codelineno-9-14" href="#__codelineno-9-14"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">0</span><span class="o">..</span><span class="n">n</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-15" name="__codelineno-9-15" href="#__codelineno-9-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-9-15" name="__codelineno-9-15" href="#__codelineno-9-15"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-9-16" name="__codelineno-9-16" href="#__codelineno-9-16"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-9-17" name="__codelineno-9-17" href="#__codelineno-9-17"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-9-18" name="__codelineno-9-18" href="#__codelineno-9-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-9-18" name="__codelineno-9-18" href="#__codelineno-9-18"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-9-19" name="__codelineno-9-19" href="#__codelineno-9-19"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-20" name="__codelineno-9-20" href="#__codelineno-9-20"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-9-21" name="__codelineno-9-21" href="#__codelineno-9-21"></a><span class="w"> </span><span class="n">state</span><span class="p">.</span><span class="n">get_mut</span><span class="p">(</span><span class="n">row</span><span class="p">).</span><span class="n">unwrap</span><span class="p">()[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;Q&quot;</span><span class="p">.</span><span class="n">into</span><span class="p">();</span>
@@ -4082,7 +4082,7 @@
<a id="__codelineno-9-42" name="__codelineno-9-42" href="#__codelineno-9-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-43" name="__codelineno-9-43" href="#__codelineno-9-43"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">cols</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="n">n</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-9-44" name="__codelineno-9-44" href="#__codelineno-9-44"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">diags1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-9-45" name="__codelineno-9-45" href="#__codelineno-9-45"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-9-45" name="__codelineno-9-45" href="#__codelineno-9-45"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">diags2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="kc">false</span><span class="p">;</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">];</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-9-46" name="__codelineno-9-46" href="#__codelineno-9-46"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">res</span>: <span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">Vec</span><span class="o">&lt;</span><span class="nb">String</span><span class="o">&gt;&gt;&gt;</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Vec</span>::<span class="n">new</span><span class="p">();</span>
<a id="__codelineno-9-47" name="__codelineno-9-47" href="#__codelineno-9-47"></a>
<a id="__codelineno-9-48" name="__codelineno-9-48" href="#__codelineno-9-48"></a><span class="w"> </span><span class="n">backtrack</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">n</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">state</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">cols</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">diags1</span><span class="p">,</span><span class="w"> </span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="n">diags2</span><span class="p">);</span>
@@ -4107,10 +4107,10 @@
<a id="__codelineno-10-13" name="__codelineno-10-13" href="#__codelineno-10-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-10-14" name="__codelineno-10-14" href="#__codelineno-10-14"></a><span class="w"> </span><span class="c1">// 遍历所有列</span>
<a id="__codelineno-10-15" name="__codelineno-10-15" href="#__codelineno-10-15"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">n</span><span class="p">;</span><span class="w"> </span><span class="n">col</span><span class="o">++</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-16" name="__codelineno-10-16" href="#__codelineno-10-16"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-10-16" name="__codelineno-10-16" href="#__codelineno-10-16"></a><span class="w"> </span><span class="c1">// 计算该格子对应的主对角线和对角线</span>
<a id="__codelineno-10-17" name="__codelineno-10-17" href="#__codelineno-10-17"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">n</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-10-18" name="__codelineno-10-18" href="#__codelineno-10-18"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">diag2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">row</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="p">;</span>
<a id="__codelineno-10-19" name="__codelineno-10-19" href="#__codelineno-10-19"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-10-19" name="__codelineno-10-19" href="#__codelineno-10-19"></a><span class="w"> </span><span class="c1">// 剪枝:不允许该格子所在列、主对角线、对角线上存在皇后</span>
<a id="__codelineno-10-20" name="__codelineno-10-20" href="#__codelineno-10-20"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">cols</span><span class="p">[</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags1</span><span class="p">[</span><span class="n">diag1</span><span class="p">]</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="o">!</span><span class="n">diags2</span><span class="p">[</span><span class="n">diag2</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-21" name="__codelineno-10-21" href="#__codelineno-10-21"></a><span class="w"> </span><span class="c1">// 尝试:将皇后放置在该格子</span>
<a id="__codelineno-10-22" name="__codelineno-10-22" href="#__codelineno-10-22"></a><span class="w"> </span><span class="n">state</span><span class="p">[</span><span class="n">row</span><span class="p">][</span><span class="n">col</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sc">&#39;Q&#39;</span><span class="p">;</span>
@@ -4136,7 +4136,7 @@
<a id="__codelineno-10-42" name="__codelineno-10-42" href="#__codelineno-10-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-10-43" name="__codelineno-10-43" href="#__codelineno-10-43"></a><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">cols</span><span class="p">[</span><span class="n">MAX_SIZE</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="nb">false</span><span class="p">};</span><span class="w"> </span><span class="c1">// 记录列是否有皇后</span>
<a id="__codelineno-10-44" name="__codelineno-10-44" href="#__codelineno-10-44"></a><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">diags1</span><span class="p">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_SIZE</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="nb">false</span><span class="p">};</span><span class="w"> </span><span class="c1">// 记录主对角线上是否有皇后</span>
<a id="__codelineno-10-45" name="__codelineno-10-45" href="#__codelineno-10-45"></a><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">diags2</span><span class="p">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_SIZE</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="nb">false</span><span class="p">};</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-10-45" name="__codelineno-10-45" href="#__codelineno-10-45"></a><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="n">diags2</span><span class="p">[</span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_SIZE</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span><span class="nb">false</span><span class="p">};</span><span class="w"> </span><span class="c1">// 记录对角线上是否有皇后</span>
<a id="__codelineno-10-46" name="__codelineno-10-46" href="#__codelineno-10-46"></a>
<a id="__codelineno-10-47" name="__codelineno-10-47" href="#__codelineno-10-47"></a><span class="w"> </span><span class="kt">char</span><span class="w"> </span><span class="o">***</span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">***</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="kt">char</span><span class="w"> </span><span class="o">**</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">MAX_SIZE</span><span class="p">);</span>
<a id="__codelineno-10-48" name="__codelineno-10-48" href="#__codelineno-10-48"></a><span class="w"> </span><span class="o">*</span><span class="n">returnSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4521,8 +4521,8 @@
<h3 id="3">3. &nbsp; 两种剪枝对比<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>请注意,虽然 <code>selected</code><code>duplicated</code> 都用于剪枝,但两者的目标不同。</p>
<ul>
<li><strong>重复选择剪枝</strong>:整个搜索过程中只有一个 <code>selected</code> 。它记录的是当前状态中包含哪些元素,其作用是防止 <code>choices</code> 中的任一元素在 <code>state</code> 中重复出现。</li>
<li><strong>相等元素剪枝</strong>:每轮选择(每个调用的 <code>backtrack</code> 函数)都包含一个 <code>duplicated</code> 。它记录的是在本轮遍历(<code>for</code> 循环)中哪些元素已被选择过,其作用是保证相等元素只被选择一次。</li>
<li><strong>重复选择剪枝</strong>:整个搜索过程中只有一个 <code>selected</code> 。它记录的是当前状态中包含哪些元素,其作用是避免某个元素在 <code>state</code> 中重复出现。</li>
<li><strong>相等元素剪枝</strong>:每轮选择(每个调用的 <code>backtrack</code> 函数)都包含一个 <code>duplicated</code> 。它记录的是在本轮遍历(<code>for</code> 循环)中哪些元素已被选择过,其作用是保证相等元素只被选择一次。</li>
</ul>
<p>图 13-9 展示了两个剪枝条件的生效范围。注意,树中的每个节点代表一个选择,从根节点到叶节点的路径上的各个节点构成一个排列。</p>
<p><a class="glightbox" href="../permutations_problem.assets/permutations_ii_pruning_summary.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="两种剪枝条件的作用范围" class="animation-figure" src="../permutations_problem.assets/permutations_ii_pruning_summary.png" /></a></p>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+3 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3525,8 +3525,8 @@
<li>在全排列问题中,如果集合中存在重复元素,则最终结果会出现重复排列。我们需要约束相等元素在每轮中只能被选择一次,这通常借助一个哈希表来实现。</li>
<li>子集和问题的目标是在给定集合中找到和为目标值的所有子集。集合不区分元素顺序,而搜索过程会输出所有顺序的结果,产生重复子集。我们在回溯前将数据进行排序,并设置一个变量来指示每一轮的遍历起始点,从而将生成重复子集的搜索分支进行剪枝。</li>
<li>对于子集和问题,数组中的相等元素会产生重复集合。我们利用数组已排序的前置条件,通过判断相邻元素是否相等实现剪枝,从而确保相等元素在每轮中只能被选中一次。</li>
<li><span class="arithmatex">\(n\)</span> 皇后问题旨在寻找将 <span class="arithmatex">\(n\)</span> 个皇后放置到 <span class="arithmatex">\(n \times n\)</span> 尺寸棋盘上的方案,要求所有皇后两两之间无法攻击对方。该问题的约束条件有行约束、列约束、主对角线和对角线约束。为满足行约束,我们采用按行放置的策略,保证每一行放置一个皇后。</li>
<li>列约束和对角线约束的处理方式类似。对于列约束,我们利用一个数组来记录每一列是否有皇后,从而指示选中的格子是否合法。对于对角线约束,我们借助两个数组来分别记录该主、对角线上是否存在皇后;难点在于找处在到同一主(副)对角线上格子满足的行列索引规律。</li>
<li><span class="arithmatex">\(n\)</span> 皇后问题旨在寻找将 <span class="arithmatex">\(n\)</span> 个皇后放置到 <span class="arithmatex">\(n \times n\)</span> 尺寸棋盘上的方案,要求所有皇后两两之间无法攻击对方。该问题的约束条件有行约束、列约束、主对角线和对角线约束。为满足行约束,我们采用按行放置的策略,保证每一行放置一个皇后。</li>
<li>列约束和对角线约束的处理方式类似。对于列约束,我们利用一个数组来记录每一列是否有皇后,从而指示选中的格子是否合法。对于对角线约束,我们借助两个数组来分别记录该主、对角线上是否存在皇后;难点在于找处在到同一主(副)对角线上格子满足的行列索引规律。</li>
</ul>
<h3 id="2-q-a">2. &nbsp; Q &amp; A<a class="headerlink" href="#2-q-a" title="Permanent link">&para;</a></h3>
<div class="admonition question">
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1854,7 +1854,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1848,7 +1848,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4076,12 +4076,12 @@
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a> <span class="k">return</span> <span class="mi">0</span>
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a><span class="k">def</span> <span class="nf">loop</span><span class="p">(</span><span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
<a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;循环 O(1)&quot;&quot;&quot;</span>
<a id="__codelineno-24-6" name="__codelineno-24-6" href="#__codelineno-24-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;循环的空间复杂度为 O(1)&quot;&quot;&quot;</span>
<a id="__codelineno-24-7" name="__codelineno-24-7" href="#__codelineno-24-7"></a> <span class="k">for</span> <span class="n">_</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<a id="__codelineno-24-8" name="__codelineno-24-8" href="#__codelineno-24-8"></a> <span class="n">function</span><span class="p">()</span>
<a id="__codelineno-24-9" name="__codelineno-24-9" href="#__codelineno-24-9"></a>
<a id="__codelineno-24-10" name="__codelineno-24-10" href="#__codelineno-24-10"></a><span class="k">def</span> <span class="nf">recur</span><span class="p">(</span><span class="n">n</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;递归 O(n)&quot;&quot;&quot;</span>
<a id="__codelineno-24-11" name="__codelineno-24-11" href="#__codelineno-24-11"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;递归的空间复杂度为 O(n)&quot;&quot;&quot;</span>
<a id="__codelineno-24-12" name="__codelineno-24-12" href="#__codelineno-24-12"></a> <span class="k">if</span> <span class="n">n</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span> <span class="k">return</span>
<a id="__codelineno-24-13" name="__codelineno-24-13" href="#__codelineno-24-13"></a> <span class="k">return</span> <span class="n">recur</span><span class="p">(</span><span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
</code></pre></div>
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1899,7 +1899,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -5469,7 +5469,7 @@ O(1) &lt; O(\log n) &lt; O(n) &lt; O(n \log n) &lt; O(n^2) &lt; O(2^n) &lt; O(n!
</div>
<h3 id="4-o2n">4. &nbsp; 指数阶 <span class="arithmatex">\(O(2^n)\)</span><a class="headerlink" href="#4-o2n" title="Permanent link">&para;</a></h3>
<p>生物学的“细胞分裂”是指数阶增长的典型例子:初始状态为 <span class="arithmatex">\(1\)</span> 个细胞,分裂一轮后变为 <span class="arithmatex">\(2\)</span> 个,分裂两轮后变为 <span class="arithmatex">\(4\)</span> 个,以此类推,分裂 <span class="arithmatex">\(n\)</span> 轮后有 <span class="arithmatex">\(2^n\)</span> 个细胞。</p>
<p>图 2-11 和以下代码模拟了细胞分裂的过程,时间复杂度为 <span class="arithmatex">\(O(2^n)\)</span> </p>
<p>图 2-11 和以下代码模拟了细胞分裂的过程,时间复杂度为 <span class="arithmatex">\(O(2^n)\)</span> </p>
<div class="tabbed-set tabbed-alternate" data-tabs="10:12"><input checked="checked" id="__tabbed_10_1" name="__tabbed_10" type="radio" /><input id="__tabbed_10_2" name="__tabbed_10" type="radio" /><input id="__tabbed_10_3" name="__tabbed_10" type="radio" /><input id="__tabbed_10_4" name="__tabbed_10" type="radio" /><input id="__tabbed_10_5" name="__tabbed_10" type="radio" /><input id="__tabbed_10_6" name="__tabbed_10" type="radio" /><input id="__tabbed_10_7" name="__tabbed_10" type="radio" /><input id="__tabbed_10_8" name="__tabbed_10" type="radio" /><input id="__tabbed_10_9" name="__tabbed_10" type="radio" /><input id="__tabbed_10_10" name="__tabbed_10" type="radio" /><input id="__tabbed_10_11" name="__tabbed_10" type="radio" /><input id="__tabbed_10_12" name="__tabbed_10" type="radio" /><div class="tabbed-labels"><label for="__tabbed_10_1">Python</label><label for="__tabbed_10_2">C++</label><label for="__tabbed_10_3">Java</label><label for="__tabbed_10_4">C#</label><label for="__tabbed_10_5">Go</label><label for="__tabbed_10_6">Swift</label><label for="__tabbed_10_7">JS</label><label for="__tabbed_10_8">TS</label><label for="__tabbed_10_9">Dart</label><label for="__tabbed_10_10">Rust</label><label for="__tabbed_10_11">C</label><label for="__tabbed_10_12">Zig</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -1731,7 +1731,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3452,8 +3452,8 @@
<p><strong>基本数据类型以二进制的形式存储在计算机中</strong>。一个二进制位即为 <span class="arithmatex">\(1\)</span> 比特。在绝大多数现代操作系统中,<span class="arithmatex">\(1\)</span> 字节(byte)由 <span class="arithmatex">\(8\)</span> 比特(bit)组成。</p>
<p>基本数据类型的取值范围取决于其占用的空间大小。下面以 Java 为例。</p>
<ul>
<li>整数类型 <code>byte</code> 占用 <span class="arithmatex">\(1\)</span> byte = <span class="arithmatex">\(8\)</span> bits ,可以表示 <span class="arithmatex">\(2^{8}\)</span> 个数字。</li>
<li>整数类型 <code>int</code> 占用 <span class="arithmatex">\(4\)</span> bytes = <span class="arithmatex">\(32\)</span> bits ,可以表示 <span class="arithmatex">\(2^{32}\)</span> 个数字。</li>
<li>整数类型 <code>byte</code> 占用 <span class="arithmatex">\(1\)</span> 字节 = <span class="arithmatex">\(8\)</span> 比特 ,可以表示 <span class="arithmatex">\(2^{8}\)</span> 个数字。</li>
<li>整数类型 <code>int</code> 占用 <span class="arithmatex">\(4\)</span> 字节 = <span class="arithmatex">\(32\)</span> 比特 ,可以表示 <span class="arithmatex">\(2^{32}\)</span> 个数字。</li>
</ul>
<p>表 3-1 列举了 Java 中各种基本数据类型的占用空间、取值范围和默认值。此表格无须死记硬背,大致理解即可,需要时可以通过查表来回忆。</p>
<p align="center"> 表 3-1 &nbsp; 基本数据类型的占用空间和取值范围 </p>
@@ -3474,7 +3474,7 @@
<tr>
<td>整数</td>
<td><code>byte</code></td>
<td>1 byte</td>
<td>1 字节</td>
<td><span class="arithmatex">\(-2^7\)</span> (<span class="arithmatex">\(-128\)</span>)</td>
<td><span class="arithmatex">\(2^7 - 1\)</span> (<span class="arithmatex">\(127\)</span>)</td>
<td><span class="arithmatex">\(0\)</span></td>
@@ -3482,7 +3482,7 @@
<tr>
<td></td>
<td><code>short</code></td>
<td>2 bytes</td>
<td>2 字节</td>
<td><span class="arithmatex">\(-2^{15}\)</span></td>
<td><span class="arithmatex">\(2^{15} - 1\)</span></td>
<td><span class="arithmatex">\(0\)</span></td>
@@ -3490,7 +3490,7 @@
<tr>
<td></td>
<td><code>int</code></td>
<td>4 bytes</td>
<td>4 字节</td>
<td><span class="arithmatex">\(-2^{31}\)</span></td>
<td><span class="arithmatex">\(2^{31} - 1\)</span></td>
<td><span class="arithmatex">\(0\)</span></td>
@@ -3498,7 +3498,7 @@
<tr>
<td></td>
<td><code>long</code></td>
<td>8 bytes</td>
<td>8 字节</td>
<td><span class="arithmatex">\(-2^{63}\)</span></td>
<td><span class="arithmatex">\(2^{63} - 1\)</span></td>
<td><span class="arithmatex">\(0\)</span></td>
@@ -3506,7 +3506,7 @@
<tr>
<td>浮点数</td>
<td><code>float</code></td>
<td>4 bytes</td>
<td>4 字节</td>
<td><span class="arithmatex">\(1.175 \times 10^{-38}\)</span></td>
<td><span class="arithmatex">\(3.403 \times 10^{38}\)</span></td>
<td><span class="arithmatex">\(0.0\text{f}\)</span></td>
@@ -3514,7 +3514,7 @@
<tr>
<td></td>
<td><code>double</code></td>
<td>8 bytes</td>
<td>8 字节</td>
<td><span class="arithmatex">\(2.225 \times 10^{-308}\)</span></td>
<td><span class="arithmatex">\(1.798 \times 10^{308}\)</span></td>
<td><span class="arithmatex">\(0.0\)</span></td>
@@ -3522,7 +3522,7 @@
<tr>
<td>字符</td>
<td><code>char</code></td>
<td>2 bytes</td>
<td>2 字节</td>
<td><span class="arithmatex">\(0\)</span></td>
<td><span class="arithmatex">\(2^{16} - 1\)</span></td>
<td><span class="arithmatex">\(0\)</span></td>
@@ -3530,7 +3530,7 @@
<tr>
<td>布尔</td>
<td><code>bool</code></td>
<td>1 byte</td>
<td>1 字节</td>
<td><span class="arithmatex">\(\text{false}\)</span></td>
<td><span class="arithmatex">\(\text{true}\)</span></td>
<td><span class="arithmatex">\(\text{false}\)</span></td>
@@ -3541,12 +3541,12 @@
<p>请注意,表 3-1 针对的是 Java 的基本数据类型的情况。每种编程语言都有各自的数据类型定义,它们的占用空间、取值范围和默认值可能会有所不同。</p>
<ul>
<li>在 Python 中,整数类型 <code>int</code> 可以是任意大小,只受限于可用内存;浮点数 <code>float</code> 是双精度 64 位;没有 <code>char</code> 类型,单个字符实际上是长度为 1 的字符串 <code>str</code></li>
<li>C 和 C++ 未明确规定基本数据类型大小,而因实现和平台各异。表 3-1 遵循 LP64 <a href="https://en.cppreference.com/w/cpp/language/types#Properties">数据模型</a>,其用于包括 Linux 和 macOS 在内的 Unix 64 位操作系统。</li>
<li>C 和 C++ 未明确规定基本数据类型大小,而因实现和平台各异。表 3-1 遵循 LP64 <a href="https://en.cppreference.com/w/cpp/language/types#Properties">数据模型</a>,其用于包括 Linux 和 macOS 在内的 Unix 64 位操作系统。</li>
<li>字符 <code>char</code> 的大小在 C 和 C++ 中为 1 字节,在大多数编程语言中取决于特定的字符编码方法,详见“字符编码”章节。</li>
<li>即使表示布尔量仅需 1 位(<span class="arithmatex">\(0\)</span><span class="arithmatex">\(1\)</span>),它在内存中通常存储为 1 字节。这是因为现代计算机 CPU 通常将 1 字节作为最小寻址内存单元。</li>
<li>即使表示布尔量仅需 1 位(<span class="arithmatex">\(0\)</span><span class="arithmatex">\(1\)</span>),它在内存中通常存储为 1 字节。这是因为现代计算机 CPU 通常将 1 字节作为最小寻址内存单元。</li>
</ul>
<p>那么,基本数据类型与数据结构之间有什么联系呢?我们知道,数据结构是在计算机中组织与存储数据的方式。这句话的主语是“结构”而非“数据”。</p>
<p>如果想表示“一排数字”,我们自然会想到使用数组。这是因为数组的线性结构可以表示数字的相邻关系和顺序关系,但至于存储的内容是整数 <code>int</code>、小数 <code>float</code> 是字符 <code>char</code> ,则与“数据结构”无关。</p>
<p>如果想表示“一排数字”,我们自然会想到使用数组。这是因为数组的线性结构可以表示数字的相邻关系和顺序关系,但至于存储的内容是整数 <code>int</code>、小数 <code>float</code> 是字符 <code>char</code> ,则与“数据结构”无关。</p>
<p>换句话说,<strong>基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”</strong>。例如以下代码,我们用相同的数据结构(数组)来存储与表示不同的基本数据类型,包括 <code>int</code><code>float</code><code>char</code><code>bool</code> 等。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
<div class="tabbed-content">
@@ -1806,7 +1806,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3575,7 +3575,7 @@
<p><a class="glightbox" href="../character_encoding.assets/ascii_table.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="ASCII 码" class="animation-figure" src="../character_encoding.assets/ascii_table.png" /></a></p>
<p align="center"> 图 3-6 &nbsp; ASCII 码 </p>
<p>然而,<strong>ASCII 码仅能够表示英文</strong>。随着计算机的全球化,诞生了一种能够表示更多语言的字符集「EASCII」。它在 ASCII 的 7 位基础上扩展到 8 位,能够表示 256 个不同的字符。</p>
<p>然而,<strong>ASCII 码仅能够表示英文</strong>。随着计算机的全球化,诞生了一种能够表示更多语言的「EASCII」字符集。它在 ASCII 的 7 位基础上扩展到 8 位,能够表示 256 个不同的字符。</p>
<p>在世界范围内,陆续出现了一批适用于不同地区的 EASCII 字符集。这些字符集的前 128 个字符统一为 ASCII 码,后 128 个字符定义不同,以适应不同语言的需求。</p>
<h2 id="342-gbk">3.4.2 &nbsp; GBK 字符集<a class="headerlink" href="#342-gbk" title="Permanent link">&para;</a></h2>
<p>后来人们发现,<strong>EASCII 码仍然无法满足许多语言的字符数量要求</strong>。比如汉字有近十万个,光日常使用的就有几千个。中国国家标准总局于 1980 年发布了「GB2312」字符集,其收录了 6763 个汉字,基本满足了汉字的计算机处理需要。</p>
@@ -3612,7 +3612,7 @@
<p>从存储空间占用的角度看,使用 UTF-8 表示英文字符非常高效,因为它仅需 1 字节;使用 UTF-16 编码某些非英文字符(例如中文)会更加高效,因为它仅需 2 字节,而 UTF-8 可能需要 3 字节。</p>
<p>从兼容性的角度看,UTF-8 的通用性最佳,许多工具和库优先支持 UTF-8 。</p>
<h2 id="345">3.4.5 &nbsp; 编程语言的字符编码<a class="headerlink" href="#345" title="Permanent link">&para;</a></h2>
<p>对于以往的大多数编程语言,程序运行中的字符串都采用 UTF-16 或 UTF-32 这类等长编码。在等长编码下,我们可以将字符串看作数组来处理,这种做法具有以下优点。</p>
<p>对于以往的大多数编程语言,程序运行中的字符串都采用 UTF-16 或 UTF-32 这类等长编码。在等长编码下,我们可以将字符串看作数组来处理,这种做法具有以下优点。</p>
<ul>
<li><strong>随机访问</strong>:UTF-16 编码的字符串可以很容易地进行随机访问。UTF-8 是一种变长编码,要想找到第 <span class="arithmatex">\(i\)</span> 个字符,我们需要从字符串的开始处遍历到第 <span class="arithmatex">\(i\)</span> 个字符,这需要 <span class="arithmatex">\(O(n)\)</span> 的时间。</li>
<li><strong>字符计数</strong>:与随机访问类似,计算 UTF-16 编码的字符串的长度也是 <span class="arithmatex">\(O(1)\)</span> 的操作。但是,计算 UTF-8 编码的字符串的长度需要遍历整个字符串。</li>
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3552,7 +3552,7 @@
<li><strong>基于数组可实现</strong>:栈、队列、哈希表、树、堆、图、矩阵、张量(维度 <span class="arithmatex">\(\geq 3\)</span> 的数组)等。</li>
<li><strong>基于链表可实现</strong>:栈、队列、哈希表、树、堆、图等。</li>
</ul>
<p>基于数组实现的数据结构也称“静态数据结构”,这意味着此类数据结构在初始化后长度不可变。相对应地,基于链表实现的数据结构称“动态数据结构”,这类数据结构在初始化后,仍可以在程序运行过程中对其长度进行调整。</p>
<p>基于数组实现的数据结构也称“静态数据结构”,这意味着此类数据结构在初始化后长度不可变。相对应地,基于链表实现的数据结构称“动态数据结构”,这类数据结构在初始化后,仍可以在程序运行过程中对其长度进行调整。</p>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>如果你感觉物理结构理解起来有困难,建议先阅读下一章,然后再回顾本节内容。</p>
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -897,7 +897,7 @@
<li class="md-nav__item">
<a href="#331" class="md-nav__link">
<span class="md-ellipsis">
3.3.1 &nbsp; 整数编
3.3.1 &nbsp; 原码、反码和补
</span>
</a>
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3463,7 +3463,7 @@
<li class="md-nav__item">
<a href="#331" class="md-nav__link">
<span class="md-ellipsis">
3.3.1 &nbsp; 整数编
3.3.1 &nbsp; 原码、反码和补
</span>
</a>
@@ -3519,7 +3519,7 @@
<p class="admonition-title">Note</p>
<p>在本书中,标题带有 * 符号的是选读章节。如果你时间有限或感到理解困难,可以先跳过,等学完必读章节后再单独攻克。</p>
</div>
<h2 id="331">3.3.1 &nbsp; 整数编<a class="headerlink" href="#331" title="Permanent link">&para;</a></h2>
<h2 id="331">3.3.1 &nbsp; 原码、反码和补<a class="headerlink" href="#331" title="Permanent link">&para;</a></h2>
<p>在上一节的表格中我们发现,所有整数类型能够表示的负数都比正数多一个,例如 <code>byte</code> 的取值范围是 <span class="arithmatex">\([-128, 127]\)</span> 。这个现象比较反直觉,它的内在原因涉及原码、反码、补码的相关知识。</p>
<p>首先需要指出,<strong>数字是以“补码”的形式存储在计算机中的</strong>。在分析这样做的原因之前,首先给出三者的定义。</p>
<ul>
@@ -3584,16 +3584,16 @@
<p>现在我们可以总结出计算机使用补码的原因:基于补码表示,计算机可以用同样的电路和操作来处理正数和负数的加法,不需要设计特殊的硬件电路来处理减法,并且无须特别处理正负零的歧义问题。这大大简化了硬件设计,提高了运算效率。</p>
<p>补码的设计非常精妙,因篇幅关系我们就先介绍到这里,建议有兴趣的读者进一步深入了解。</p>
<h2 id="332">3.3.2 &nbsp; 浮点数编码<a class="headerlink" href="#332" title="Permanent link">&para;</a></h2>
<p>细心的你可能会发现:<code>int</code><code>float</code> 长度相同,都是 4 bytes ,但为什么 <code>float</code> 的取值范围远大于 <code>int</code> ?这非常反直觉,因为按理说 <code>float</code> 需要表示小数,取值范围应该变小才对。</p>
<p>实际上,<strong>这是因为浮点数 <code>float</code> 采用了不同的表示方式</strong>。记一个 32-bit 长度的二进制数为:</p>
<p>细心的你可能会发现:<code>int</code><code>float</code> 长度相同,都是 4 字节 ,但为什么 <code>float</code> 的取值范围远大于 <code>int</code> ?这非常反直觉,因为按理说 <code>float</code> 需要表示小数,取值范围应该变小才对。</p>
<p>实际上,<strong>这是因为浮点数 <code>float</code> 采用了不同的表示方式</strong>。记一个 32 长度的二进制数为:</p>
<div class="arithmatex">\[
b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0
\]</div>
<p>根据 IEEE 754 标准,32-bit 长度的 <code>float</code> 由以下三个部分构成。</p>
<ul>
<li>符号位 <span class="arithmatex">\(\mathrm{S}\)</span> :占 1 bit ,对应 <span class="arithmatex">\(b_{31}\)</span></li>
<li>指数位 <span class="arithmatex">\(\mathrm{E}\)</span> :占 8 bits ,对应 <span class="arithmatex">\(b_{30} b_{29} \ldots b_{23}\)</span></li>
<li>分数位 <span class="arithmatex">\(\mathrm{N}\)</span> :占 23 bits ,对应 <span class="arithmatex">\(b_{22} b_{21} \ldots b_0\)</span></li>
<li>符号位 <span class="arithmatex">\(\mathrm{S}\)</span> :占 1 ,对应 <span class="arithmatex">\(b_{31}\)</span></li>
<li>指数位 <span class="arithmatex">\(\mathrm{E}\)</span> :占 8 ,对应 <span class="arithmatex">\(b_{30} b_{29} \ldots b_{23}\)</span></li>
<li>分数位 <span class="arithmatex">\(\mathrm{N}\)</span> :占 23 ,对应 <span class="arithmatex">\(b_{22} b_{21} \ldots b_0\)</span></li>
</ul>
<p>二进制数 <code>float</code> 对应值的计算方法为:</p>
<div class="arithmatex">\[
+7 -7
View File
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3525,8 +3525,8 @@
<li>原码、反码和补码是在计算机中编码数字的三种方法,它们之间可以相互转换。整数的原码的最高位是符号位,其余位是数字的值。</li>
<li>整数在计算机中是以补码的形式存储的。在补码表示下,计算机可以对正数和负数的加法一视同仁,不需要为减法操作单独设计特殊的硬件电路,并且不存在正负零歧义的问题。</li>
<li>浮点数的编码由 1 位符号位、8 位指数位和 23 位分数位构成。由于存在指数位,因此浮点数的取值范围远大于整数,代价是牺牲了精度。</li>
<li>ASCII 码是最早出现的英文字符集,长度为 1 字节,共收录 127 个字符。GBK 字符集是常用的中文字符集,共收录两万多个汉字。Unicode 致力于提供一个完整的字符集标准,收录世界各种语言的字符,从而解决由于字符编码方法不一致而导致的乱码问题。</li>
<li>UTF-8 是最受欢迎的 Unicode 编码方法,通用性非常好。它是一种变长的编码方法,具有很好的扩展性,有效提升了存储空间的使用效率。UTF-16 和 UTF-32 是等长的编码方法。在编码中文时,UTF-16 比 UTF-8 的占用空间更小。Java 和 C# 等编程语言默认使用 UTF-16 编码。</li>
<li>ASCII 码是最早出现的英文字符集,长度为 1 字节,共收录 127 个字符。GBK 字符集是常用的中文字符集,共收录两万多个汉字。Unicode 致力于提供一个完整的字符集标准,收录世界各种语言的字符,从而解决由于字符编码方法不一致而导致的乱码问题。</li>
<li>UTF-8 是最受欢迎的 Unicode 编码方法,通用性非常好。它是一种变长的编码方法,具有很好的扩展性,有效提升了存储空间的使用效率。UTF-16 和 UTF-32 是等长的编码方法。在编码中文时,UTF-16 占用的空间比 UTF-8 更小。Java 和 C# 等编程语言默认使用 UTF-16 编码。</li>
</ul>
<h3 id="2-q-a">2. &nbsp; Q &amp; A<a class="headerlink" href="#2-q-a" title="Permanent link">&para;</a></h3>
<div class="admonition question">
@@ -3535,16 +3535,16 @@
从存储的角度来看,哈希表的底层是数组,其中每一个桶槽位可能包含一个值,也可能包含一个链表或一棵树。因此,哈希表可能同时包含线性数据结构(数组、链表)和非线性数据结构(树)。</p>
</div>
<div class="admonition question">
<p class="admonition-title"><code>char</code> 类型的长度是 1 byte 吗?</p>
<p><code>char</code> 类型的长度由编程语言采用的编码方法决定。例如,Java、JavaScript、TypeScript、C# 都采用 UTF-16 编码(保存 Unicode 码点),因此 char 类型的长度为 2 bytes</p>
<p class="admonition-title"><code>char</code> 类型的长度是 1 字节吗?</p>
<p><code>char</code> 类型的长度由编程语言采用的编码方法决定。例如,Java、JavaScript、TypeScript、C# 都采用 UTF-16 编码(保存 Unicode 码点),因此 <code>char</code> 类型的长度为 2 字节</p>
</div>
<div class="admonition question">
<p class="admonition-title">基于数组实现的数据结构也称“静态数据结构” 是否有歧义?因为栈也可以进行出栈和入栈等操作,这些操作都是“动态”的。</p>
<p class="admonition-title">基于数组实现的数据结构也称“静态数据结构” 是否有歧义?栈也可以进行出栈和入栈等操作,这些操作都是“动态”的。</p>
<p>栈确实可以实现动态的数据操作,但数据结构仍然是“静态”(长度不可变)的。尽管基于数组的数据结构可以动态地添加或删除元素,但它们的容量是固定的。如果数据量超出了预分配的大小,就需要创建一个新的更大的数组,并将旧数组的内容复制到新数组中。</p>
</div>
<div class="admonition question">
<p class="admonition-title">在构建栈(队列)的时候,未指定它的大小,为什么它们是“静态数据结构”呢?</p>
<p>在高级编程语言中,我们无须人工指定栈(队列)的初始容量,这个工作由类内部自动完成。例如,Java 的 ArrayList 的初始容量通常为 10。另外,扩容操作也是自动实现的。详见后续的“列表”章节。</p>
<p>在高级编程语言中,我们无须人工指定栈(队列)的初始容量,这个工作由类内部自动完成。例如,Java 的 <code>ArrayList</code> 的初始容量通常为 10。另外,扩容操作也是自动实现的。详见后续的“列表”章节。</p>
</div>
<!-- Source file information -->
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3576,7 +3576,7 @@
<ol>
<li>前序遍历的首元素 3 是根节点的值。</li>
<li>查找根节点 3 在 <code>inorder</code> 中的索引,利用该索引可将 <code>inorder</code> 划分为 <code>[ 9 | 3 1 2 7 ]</code></li>
<li>根据 <code>inorder</code> 划分结果,易得左子树和右子树的节点数量分别为 1 和 3 ,从而可将 <code>preorder</code> 划分为 <code>[ 3 | 9 | 2 1 7 ]</code></li>
<li>根据 <code>inorder</code> 划分结果,易得左子树和右子树的节点数量分别为 1 和 3 ,从而可将 <code>preorder</code> 划分为 <code>[ 3 | 9 | 2 1 7 ]</code></li>
</ol>
<p><a class="glightbox" href="../build_binary_tree_problem.assets/build_tree_preorder_inorder_division.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="在前序遍历和中序遍历中划分子树" class="animation-figure" src="../build_binary_tree_problem.assets/build_tree_preorder_inorder_division.png" /></a></p>
<p align="center"> 图 12-6 &nbsp; 在前序遍历和中序遍历中划分子树 </p>
@@ -3619,7 +3619,7 @@
</tbody>
</table>
</div>
<p>请注意,右子树根节点索引中的 <span class="arithmatex">\((m-l)\)</span> 的含义是“左子树的节点数量”,建议合图 12-7 理解。</p>
<p>请注意,右子树根节点索引中的 <span class="arithmatex">\((m-l)\)</span> 的含义是“左子树的节点数量”,建议合图 12-7 理解。</p>
<p><a class="glightbox" href="../build_binary_tree_problem.assets/build_tree_division_pointers.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="根节点和左右子树的索引区间表示" class="animation-figure" src="../build_binary_tree_problem.assets/build_tree_division_pointers.png" /></a></p>
<p align="center"> 图 12-7 &nbsp; 根节点和左右子树的索引区间表示 </p>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3601,7 +3601,7 @@
<li><strong>子问题是独立的</strong>:子问题之间没有重叠,互不依赖,可以独立解决。</li>
<li><strong>子问题的解可以合并</strong>:原问题的解通过合并子问题的解得来。</li>
</ol>
<p>显然,归并排序满足以上三判断依据。</p>
<p>显然,归并排序满足以上三判断依据。</p>
<ol>
<li><strong>问题可以分解</strong>:递归地将数组(原问题)划分为两个子数组(子问题)。</li>
<li><strong>子问题是独立的</strong>:每个子数组都可以独立地进行排序(子问题可以独立进行求解)。</li>
@@ -3645,7 +3645,7 @@ n(n - 4) &amp; &gt; 0
<li><strong>汉诺塔问题</strong>:汉诺塔问题可以通过递归解决,这是典型的分治策略应用。</li>
<li><strong>求解逆序对</strong>:在一个序列中,如果前面的数字大于后面的数字,那么这两个数字构成一个逆序对。求解逆序对问题可以利用分治的思想,借助归并排序进行求解。</li>
</ul>
<p>另一方面,分治在算法和数据结构的设计中应用非常广泛。</p>
<p>另一方面,分治在算法和数据结构的设计中应用非常广泛。</p>
<ul>
<li><strong>二分查找</strong>:二分查找是将有序数组从中点索引处分为两部分,然后根据目标值与中间元素值比较结果,决定排除哪一半区间,并在剩余区间执行相同的二分操作。</li>
<li><strong>归并排序</strong>:本节开头已介绍,不再赘述。</li>
@@ -3653,7 +3653,7 @@ n(n - 4) &amp; &gt; 0
<li><strong>桶排序</strong>:桶排序的基本思想是将数据分散到多个桶,然后对每个桶内的元素进行排序,最后将各个桶的元素依次取出,从而得到一个有序数组。</li>
<li><strong></strong>:例如二叉搜索树、AVL 树、红黑树、B 树、B+ 树等,它们的查找、插入和删除等操作都可以视为分治策略的应用。</li>
<li><strong></strong>:堆是一种特殊的完全二叉树,其各种操作,如插入、删除和堆化,实际上都隐含了分治的思想。</li>
<li><strong>哈希表</strong>:虽然哈希表并不直接应用分治,但某些哈希冲突解决方案间接应用了分治策略,例如,链式地址中的长链表会被转化为红黑树,以提升查询效率。</li>
<li><strong>哈希表</strong>:虽然哈希表并不直接应用分治,但某些哈希冲突解决方案间接应用了分治策略,例如,链式地址中的长链表会被转化为红黑树,以提升查询效率。</li>
</ul>
<p>可以看出,<strong>分治是一种“润物细无声”的算法思想</strong>,隐含在各种算法与数据结构之中。</p>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3552,14 +3552,14 @@
<div class="tabbed-set tabbed-alternate" data-tabs="1:2"><input checked="checked" id="__tabbed_1_1" name="__tabbed_1" type="radio" /><input id="__tabbed_1_2" 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></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f1_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 1 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f1_step1.png" /></a></p>
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f1_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 1 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f1_step1.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f1_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="hanota_f1_step2" class="animation-figure" src="../hanota_problem.assets/hanota_f1_step2.png" /></a></p>
</div>
</div>
</div>
<p align="center"> 图 12-11 &nbsp; 规模为 1 问题的解 </p>
<p align="center"> 图 12-11 &nbsp; 规模为 1 问题的解 </p>
<p>如图 12-12 所示,对于问题 <span class="arithmatex">\(f(2)\)</span> ,即当有两个圆盘时,<strong>由于要时刻满足小圆盘在大圆盘之上,因此需要借助 <code>B</code> 来完成移动</strong></p>
<ol>
@@ -3570,7 +3570,7 @@
<div class="tabbed-set tabbed-alternate" data-tabs="2:4"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1">&lt;1&gt;</label><label for="__tabbed_2_2">&lt;2&gt;</label><label for="__tabbed_2_3">&lt;3&gt;</label><label for="__tabbed_2_4">&lt;4&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f2_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 2 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f2_step1.png" /></a></p>
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f2_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 2 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f2_step1.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f2_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="hanota_f2_step2" class="animation-figure" src="../hanota_problem.assets/hanota_f2_step2.png" /></a></p>
@@ -3583,7 +3583,7 @@
</div>
</div>
</div>
<p align="center"> 图 12-12 &nbsp; 规模为 2 问题的解 </p>
<p align="center"> 图 12-12 &nbsp; 规模为 2 问题的解 </p>
<p>解决问题 <span class="arithmatex">\(f(2)\)</span> 的过程可总结为:<strong>将两个圆盘借助 <code>B</code><code>A</code> 移至 <code>C</code></strong> 。其中,<code>C</code> 称为目标柱、<code>B</code> 称为缓冲柱。</p>
<h3 id="2">2. &nbsp; 子问题分解<a class="headerlink" href="#2" title="Permanent link">&para;</a></h3>
@@ -3597,7 +3597,7 @@
<div class="tabbed-set tabbed-alternate" data-tabs="3:4"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">&lt;1&gt;</label><label for="__tabbed_3_2">&lt;2&gt;</label><label for="__tabbed_3_3">&lt;3&gt;</label><label for="__tabbed_3_4">&lt;4&gt;</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f3_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 3 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f3_step1.png" /></a></p>
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f3_step1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="规模为 3 问题的解" class="animation-figure" src="../hanota_problem.assets/hanota_f3_step1.png" /></a></p>
</div>
<div class="tabbed-block">
<p><a class="glightbox" href="../hanota_problem.assets/hanota_f3_step2.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="hanota_f3_step2" class="animation-figure" src="../hanota_problem.assets/hanota_f3_step2.png" /></a></p>
@@ -3610,9 +3610,9 @@
</div>
</div>
</div>
<p align="center"> 图 12-13 &nbsp; 规模为 3 问题的解 </p>
<p align="center"> 图 12-13 &nbsp; 规模为 3 问题的解 </p>
<p>从本质上看,<strong>我们将问题 <span class="arithmatex">\(f(3)\)</span> 划分为两个子问题 <span class="arithmatex">\(f(2)\)</span> 和子问题 <span class="arithmatex">\(f(1)\)</span></strong> 。按顺序解决这三个子问题之后,原问题随之得到解决。这说明子问题是独立的,而且解可以合并。</p>
<p>从本质上看,<strong>我们将问题 <span class="arithmatex">\(f(3)\)</span> 划分为两个子问题 <span class="arithmatex">\(f(2)\)</span>一个子问题 <span class="arithmatex">\(f(1)\)</span></strong> 。按顺序解决这三个子问题之后,原问题随之得到解决。这说明子问题是独立的,而且解可以合并。</p>
<p>至此,我们可总结出图 12-14 所示的解决汉诺塔问题的分治策略:将原问题 <span class="arithmatex">\(f(n)\)</span> 划分为两个子问题 <span class="arithmatex">\(f(n-1)\)</span> 和一个子问题 <span class="arithmatex">\(f(1)\)</span> ,并按照以下顺序解决这三个子问题。</p>
<ol>
<li><span class="arithmatex">\(n-1\)</span> 个圆盘借助 <code>C</code><code>A</code> 移至 <code>B</code></li>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4003,7 +4003,7 @@ dp[i] = \min(dp[i-1], dp[i-2]) + cost[i]
<p><a class="glightbox" href="../dp_problem_features.assets/climbing_stairs_constraint_example.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="带约束爬到第 3 阶的方案数量" class="animation-figure" src="../dp_problem_features.assets/climbing_stairs_constraint_example.png" /></a></p>
<p align="center"> 图 14-8 &nbsp; 带约束爬到第 3 阶的方案数量 </p>
<p>在该问题中,如果上一轮是跳 <span class="arithmatex">\(1\)</span> 阶上来的,那么下一轮就必须跳 <span class="arithmatex">\(2\)</span> 阶。这意味着,<strong>下一步选择不能由当前状态(当前所在楼梯阶数)独立决定,还和前一个状态(上轮所在楼梯阶数)有关</strong></p>
<p>在该问题中,如果上一轮是跳 <span class="arithmatex">\(1\)</span> 阶上来的,那么下一轮就必须跳 <span class="arithmatex">\(2\)</span> 阶。这意味着,<strong>下一步选择不能由当前状态(当前所在楼梯阶数)独立决定,还和前一个状态(上轮所在楼梯阶数)有关</strong></p>
<p>不难发现,此问题已不满足无后效性,状态转移方程 <span class="arithmatex">\(dp[i] = dp[i-1] + dp[i-2]\)</span> 也失效了,因为 <span class="arithmatex">\(dp[i-1]\)</span> 代表本轮跳 <span class="arithmatex">\(1\)</span> 阶,但其中包含了许多“上一轮是跳 <span class="arithmatex">\(1\)</span> 阶上来的”方案,而为了满足约束,我们就不能将 <span class="arithmatex">\(dp[i-1]\)</span> 直接计入 <span class="arithmatex">\(dp[i]\)</span> 中。</p>
<p>为此,我们需要扩展状态定义:<strong>状态 <span class="arithmatex">\([i, j]\)</span> 表示处在第 <span class="arithmatex">\(i\)</span> 阶并且上一轮跳了 <span class="arithmatex">\(j\)</span></strong>,其中 <span class="arithmatex">\(j \in \{1, 2\}\)</span> 。此状态定义有效地区分了上一轮跳了 <span class="arithmatex">\(1\)</span> 阶还是 <span class="arithmatex">\(2\)</span> 阶,我们可以据此判断当前状态是从何而来的。</p>
<ul>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3618,7 +3618,7 @@
<li>问题的目标是找出所有可能的解决方案,而不是找出最优解。</li>
<li>问题描述中有明显的排列组合的特征,需要返回具体的多个方案。</li>
</ul>
<p>如果一个问题满足决策树模型,并具有较为明显的“加分项,我们就可以假设它是一个动态规划问题,并在求解过程中验证它。</p>
<p>如果一个问题满足决策树模型,并具有较为明显的“加分项,我们就可以假设它是一个动态规划问题,并在求解过程中验证它。</p>
<h2 id="1432">14.3.2 &nbsp; 问题求解步骤<a class="headerlink" href="#1432" title="Permanent link">&para;</a></h2>
<p>动态规划的解题流程会因问题的性质和难度而有所不同,但通常遵循以下步骤:描述决策,定义状态,建立 <span class="arithmatex">\(dp\)</span> 表,推导状态转移方程,确定边界条件等。</p>
<p>为了更形象地展示解题步骤,我们使用一个经典问题“最小路径和”来举例。</p>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4134,7 +4134,7 @@ dp[i] = dp[i-1] + dp[i-2]
<p align="center"> 图 14-3 &nbsp; 爬楼梯对应递归树 </p>
<p>观察图 14-3 <strong>指数阶的时间复杂度是“重叠子问题”导致的</strong>。例如 <span class="arithmatex">\(dp[9]\)</span> 被分解为 <span class="arithmatex">\(dp[8]\)</span><span class="arithmatex">\(dp[7]\)</span> <span class="arithmatex">\(dp[8]\)</span> 被分解为 <span class="arithmatex">\(dp[7]\)</span><span class="arithmatex">\(dp[6]\)</span> ,两者都包含子问题 <span class="arithmatex">\(dp[7]\)</span></p>
<p>以此类推,子问题中包含更小的重叠子问题,子子孙孙无穷尽也。绝大部分计算资源都浪费在这些重叠的问题上。</p>
<p>以此类推,子问题中包含更小的重叠子问题,子子孙孙无穷尽也。绝大部分计算资源都浪费在这些重叠的问题上。</p>
<h2 id="1412">14.1.2 &nbsp; 方法二:记忆化搜索<a class="headerlink" href="#1412" title="Permanent link">&para;</a></h2>
<p>为了提升算法效率,<strong>我们希望所有的重叠子问题都只被计算一次</strong>。为此,我们声明一个数组 <code>mem</code> 来记录每个子问题的解,并在搜索过程中将重叠子问题剪枝。</p>
<ol>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3442,9 +3442,9 @@
<!-- Page content -->
<h1 id="147">14.7 &nbsp; 小结<a class="headerlink" href="#147" title="Permanent link">&para;</a></h1>
<ul>
<li>动态规划对问题进行分解,并通过存储子问题的解来规避重复计算,提高 计算效率。</li>
<li>动态规划对问题进行分解,并通过存储子问题的解来规避重复计算,提高计算效率。</li>
<li>不考虑时间的前提下,所有动态规划问题都可以用回溯(暴力搜索)进行求解,但递归树中存在大量的重叠子问题,效率极低。通过引入记忆化列表,可以存储所有计算过的子问题的解,从而保证重叠子问题只被计算一次。</li>
<li>记忆化递归是一种从顶至底的递归式解法,而与之对应的动态规划是一种从底至顶的递推式解法,其如同“填写表格”一样。由于当前状态仅依赖某些局部状态,因此我们可以消除 <span class="arithmatex">\(dp\)</span> 表的一个维度,从而降低空间复杂度。</li>
<li>记忆化搜索是一种从顶至底的递归式解法,而与之对应的动态规划是一种从底至顶的递推式解法,其如同“填写表格”一样。由于当前状态仅依赖某些局部状态,因此我们可以消除 <span class="arithmatex">\(dp\)</span> 表的一个维度,从而降低空间复杂度。</li>
<li>子问题分解是一种通用的算法思路,在分治、动态规划、回溯中具有不同的性质。</li>
<li>动态规划问题有三大特性:重叠子问题、最优子结构、无后效性。</li>
<li>如果原问题的最优解可以从子问题的最优解构建得来,则它就具有最优子结构。</li>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+5 -5
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1919,7 +1919,7 @@
<li class="md-nav__item">
<a href="#913" class="md-nav__link">
<span class="md-ellipsis">
9.1.3 &nbsp; 图常见应用
9.1.3 &nbsp;常见应用
</span>
</a>
@@ -3538,7 +3538,7 @@
<li class="md-nav__item">
<a href="#913" class="md-nav__link">
<span class="md-ellipsis">
9.1.3 &nbsp; 图常见应用
9.1.3 &nbsp;常见应用
</span>
</a>
@@ -3610,7 +3610,7 @@ G &amp; = \{ V, E \} \newline
<p><a class="glightbox" href="../graph.assets/connected_graph.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="连通图与非连通图" class="animation-figure" src="../graph.assets/connected_graph.png" /></a></p>
<p align="center"> 图 9-3 &nbsp; 连通图与非连通图 </p>
<p>我们还可以为边添加“权重”变量,从而得到如图 9-4 所示的「有权图 weighted graph」。例如在王者荣耀等手游中,系统会根据共同游戏时间来计算玩家之间的“亲密度”,这种亲密度网络就可以用有权图来表示。</p>
<p>我们还可以为边添加“权重”变量,从而得到如图 9-4 所示的「有权图 weighted graph」。例如在王者荣耀等手游中,系统会根据共同游戏时间来计算玩家之间的“亲密度”,这种亲密度网络就可以用有权图来表示。</p>
<p><a class="glightbox" href="../graph.assets/weighted_graph.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="有权图与无权图" class="animation-figure" src="../graph.assets/weighted_graph.png" /></a></p>
<p align="center"> 图 9-4 &nbsp; 有权图与无权图 </p>
@@ -3642,7 +3642,7 @@ G &amp; = \{ V, E \} \newline
<p>邻接表仅存储实际存在的边,而边的总数通常远小于 <span class="arithmatex">\(n^2\)</span> ,因此它更加节省空间。然而,在邻接表中需要通过遍历链表来查找边,因此其时间效率不如邻接矩阵。</p>
<p>观察图 9-6 <strong>邻接表结构与哈希表中的“链式地址”非常相似,因此我们也可以采用类似的方法来优化效率</strong>。比如当链表较长时,可以将链表转化为 AVL 树或红黑树,从而将时间效率从 <span class="arithmatex">\(O(n)\)</span> 优化至 <span class="arithmatex">\(O(\log n)\)</span> ;还可以把链表转换为哈希表,从而将时间复杂度降至 <span class="arithmatex">\(O(1)\)</span></p>
<h2 id="913">9.1.3 &nbsp; 图常见应用<a class="headerlink" href="#913" title="Permanent link">&para;</a></h2>
<h2 id="913">9.1.3 &nbsp;常见应用<a class="headerlink" href="#913" title="Permanent link">&para;</a></h2>
<p>如表 9-1 所示,许多现实系统可以用图来建模,相应的问题也可以约化为图计算问题。</p>
<p align="center"> 表 9-1 &nbsp; 现实生活中常见的图 </p>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+35 -35
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3612,7 +3612,7 @@
<!-- Page content -->
<h1 id="93">9.3 &nbsp; 图的遍历<a class="headerlink" href="#93" title="Permanent link">&para;</a></h1>
<p>树代表的是“一对多”的关系,而图则具有更高的自由度,可以表示任意的“多对多”关系。因此,我们可以把树看作图的一种特例。显然,<strong>树的遍历操作也是图的遍历操作的一种特例</strong></p>
<p>图和树都需要应用搜索算法来实现遍历操作。图的遍历方式可分为两种:「广度优先遍历 breadth-first traversal」和「深度优先遍历 depth-first traversal」。它们也常被称为「广度优先搜索 breadth-first search」和「深度优先搜索 depth-first search」,简称 BFS 和 DFS </p>
<p>图和树都需要应用搜索算法来实现遍历操作。图的遍历方式可分为两种:「广度优先遍历」和「深度优先遍历」</p>
<h2 id="931">9.3.1 &nbsp; 广度优先遍历<a class="headerlink" href="#931" title="Permanent link">&para;</a></h2>
<p><strong>广度优先遍历是一种由近及远的遍历方式,从某个节点出发,始终优先访问距离最近的顶点,并一层层向外扩张</strong>。如图 9-9 所示,从左上角顶点出发,首先遍历该顶点的所有邻接顶点,然后遍历下一个顶点的所有邻接顶点,以此类推,直至所有顶点访问完毕。</p>
<p><a class="glightbox" href="../graph_traversal.assets/graph_bfs.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="图的广度优先遍历" class="animation-figure" src="../graph_traversal.assets/graph_bfs.png" /></a></p>
@@ -3630,7 +3630,7 @@
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.py</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="k">def</span> <span class="nf">graph_bfs</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">start_vet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Vertex</span><span class="p">]:</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;广度优先遍历 BFS&quot;&quot;&quot;</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;广度优先遍历&quot;&quot;&quot;</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="c1"># 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="c1"># 顶点遍历序列</span>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
@@ -3653,7 +3653,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.cpp</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.cpp</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="n">vector</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="w"> </span><span class="o">*&gt;</span><span class="w"> </span><span class="n">graphBFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">&amp;</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3682,7 +3682,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.java</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.java</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="nf">graphBFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3711,7 +3711,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.cs</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.cs</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">GraphBFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3740,7 +3740,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.go</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.go</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="kd">func</span><span class="w"> </span><span class="nx">graphBFS</span><span class="p">(</span><span class="nx">g</span><span class="w"> </span><span class="o">*</span><span class="nx">graphAdjList</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="w"> </span><span class="nx">Vertex</span><span class="p">)</span><span class="w"> </span><span class="p">[]</span><span class="nx">Vertex</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3774,7 +3774,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.swift</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.swift</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a><span class="kd">func</span> <span class="nf">graphBFS</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">startVet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="p">[</span><span class="n">Vertex</span><span class="p">]</span> <span class="p">{</span>
<a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> <span class="c1">// 顶点遍历序列</span>
@@ -3802,7 +3802,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.js</span><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.js</span><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="kd">function</span><span class="w"> </span><span class="nx">graphBFS</span><span class="p">(</span><span class="nx">graph</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3831,7 +3831,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.ts</span><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.ts</span><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="kd">function</span><span class="w"> </span><span class="nx">graphBFS</span><span class="p">(</span><span class="nx">graph</span><span class="o">:</span><span class="w"> </span><span class="kt">GraphAdjList</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="o">:</span><span class="w"> </span><span class="kt">Vertex</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nx">Vertex</span><span class="p">[]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3860,7 +3860,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.dart</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.dart</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">graphBFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3890,7 +3890,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_bfs.rs</span><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<div class="highlight"><span class="filename">graph_bfs.rs</span><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="k">fn</span> <span class="nf">graph_bfs</span><span class="p">(</span><span class="n">graph</span>: <span class="nc">GraphAdjList</span><span class="p">,</span><span class="w"> </span><span class="n">start_vet</span>: <span class="nc">Vertex</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -3965,7 +3965,7 @@
<a id="__codelineno-10-41" name="__codelineno-10-41" href="#__codelineno-10-41"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-10-42" name="__codelineno-10-42" href="#__codelineno-10-42"></a><span class="p">}</span>
<a id="__codelineno-10-43" name="__codelineno-10-43" href="#__codelineno-10-43"></a>
<a id="__codelineno-10-44" name="__codelineno-10-44" href="#__codelineno-10-44"></a><span class="cm">/* 广度优先遍历 BFS */</span>
<a id="__codelineno-10-44" name="__codelineno-10-44" href="#__codelineno-10-44"></a><span class="cm">/* 广度优先遍历 */</span>
<a id="__codelineno-10-45" name="__codelineno-10-45" href="#__codelineno-10-45"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-10-46" name="__codelineno-10-46" href="#__codelineno-10-46"></a><span class="kt">void</span><span class="w"> </span><span class="nf">graphBFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">*</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">startVet</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">**</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">resSize</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">**</span><span class="n">visited</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">visitedSize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-47" name="__codelineno-10-47" href="#__codelineno-10-47"></a><span class="w"> </span><span class="c1">// 队列用于实现 BFS</span>
@@ -4056,7 +4056,7 @@
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.py</span><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="k">def</span> <span class="nf">dfs</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">visited</span><span class="p">:</span> <span class="nb">set</span><span class="p">[</span><span class="n">Vertex</span><span class="p">],</span> <span class="n">res</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">Vertex</span><span class="p">],</span> <span class="n">vet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">):</span>
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;深度优先遍历 DFS 辅助函数&quot;&quot;&quot;</span>
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;深度优先遍历辅助函数&quot;&quot;&quot;</span>
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> <span class="n">res</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">vet</span><span class="p">)</span> <span class="c1"># 记录访问顶点</span>
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a> <span class="n">visited</span><span class="o">.</span><span class="n">add</span><span class="p">(</span><span class="n">vet</span><span class="p">)</span> <span class="c1"># 标记该顶点已被访问</span>
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a> <span class="c1"># 遍历该顶点的所有邻接顶点</span>
@@ -4067,7 +4067,7 @@
<a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a> <span class="n">dfs</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span> <span class="n">visited</span><span class="p">,</span> <span class="n">res</span><span class="p">,</span> <span class="n">adjVet</span><span class="p">)</span>
<a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a>
<a id="__codelineno-12-12" name="__codelineno-12-12" href="#__codelineno-12-12"></a><span class="k">def</span> <span class="nf">graph_dfs</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">start_vet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">list</span><span class="p">[</span><span class="n">Vertex</span><span class="p">]:</span>
<a id="__codelineno-12-13" name="__codelineno-12-13" href="#__codelineno-12-13"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;深度优先遍历 DFS&quot;&quot;&quot;</span>
<a id="__codelineno-12-13" name="__codelineno-12-13" href="#__codelineno-12-13"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;深度优先遍历&quot;&quot;&quot;</span>
<a id="__codelineno-12-14" name="__codelineno-12-14" href="#__codelineno-12-14"></a> <span class="c1"># 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-12-15" name="__codelineno-12-15" href="#__codelineno-12-15"></a> <span class="c1"># 顶点遍历序列</span>
<a id="__codelineno-12-16" name="__codelineno-12-16" href="#__codelineno-12-16"></a> <span class="n">res</span> <span class="o">=</span> <span class="p">[]</span>
@@ -4078,7 +4078,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.cpp</span><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.cpp</span><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="kt">void</span><span class="w"> </span><span class="nf">dfs</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">&amp;</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">unordered_set</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="w"> </span><span class="o">*&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">visited</span><span class="p">,</span><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="w"> </span><span class="o">*&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">vet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a><span class="w"> </span><span class="n">res</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录访问顶点</span>
<a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="w"> </span><span class="n">visited</span><span class="p">.</span><span class="n">emplace</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 标记该顶点已被访问</span>
@@ -4091,7 +4091,7 @@
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a><span class="p">}</span>
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="n">vector</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="w"> </span><span class="o">*&gt;</span><span class="w"> </span><span class="n">graphDFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">&amp;</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4104,7 +4104,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.java</span><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.java</span><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="kt">void</span><span class="w"> </span><span class="nf">dfs</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Set</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">visited</span><span class="p">,</span><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">vet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="w"> </span><span class="n">res</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录访问顶点</span>
<a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="w"> </span><span class="n">visited</span><span class="p">.</span><span class="na">add</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 标记该顶点已被访问</span>
@@ -4117,7 +4117,7 @@
<a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-12" name="__codelineno-14-12" href="#__codelineno-14-12"></a><span class="p">}</span>
<a id="__codelineno-14-13" name="__codelineno-14-13" href="#__codelineno-14-13"></a>
<a id="__codelineno-14-14" name="__codelineno-14-14" href="#__codelineno-14-14"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-14-14" name="__codelineno-14-14" href="#__codelineno-14-14"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-14-15" name="__codelineno-14-15" href="#__codelineno-14-15"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-14-16" name="__codelineno-14-16" href="#__codelineno-14-16"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="nf">graphDFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-17" name="__codelineno-14-17" href="#__codelineno-14-17"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4130,7 +4130,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.cs</span><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.cs</span><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="k">void</span><span class="w"> </span><span class="nf">DFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">visited</span><span class="p">,</span><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">vet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="w"> </span><span class="n">res</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录访问顶点</span>
<a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="w"> </span><span class="n">visited</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 标记该顶点已被访问</span>
@@ -4144,7 +4144,7 @@
<a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="p">}</span>
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a>
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-15-17" name="__codelineno-15-17" href="#__codelineno-15-17"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">GraphDFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-18" name="__codelineno-15-18" href="#__codelineno-15-18"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4157,7 +4157,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.go</span><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.go</span><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="kd">func</span><span class="w"> </span><span class="nx">dfs</span><span class="p">(</span><span class="nx">g</span><span class="w"> </span><span class="o">*</span><span class="nx">graphAdjList</span><span class="p">,</span><span class="w"> </span><span class="nx">visited</span><span class="w"> </span><span class="kd">map</span><span class="p">[</span><span class="nx">Vertex</span><span class="p">]</span><span class="kd">struct</span><span class="p">{},</span><span class="w"> </span><span class="nx">res</span><span class="w"> </span><span class="o">*</span><span class="p">[]</span><span class="nx">Vertex</span><span class="p">,</span><span class="w"> </span><span class="nx">vet</span><span class="w"> </span><span class="nx">Vertex</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="w"> </span><span class="c1">// append 操作会返回新的的引用,必须让原引用重新赋值为新slice的引用</span>
<a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="w"> </span><span class="o">*</span><span class="nx">res</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nb">append</span><span class="p">(</span><span class="o">*</span><span class="nx">res</span><span class="p">,</span><span class="w"> </span><span class="nx">vet</span><span class="p">)</span>
@@ -4172,7 +4172,7 @@
<a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="p">}</span>
<a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a>
<a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-16-17" name="__codelineno-16-17" href="#__codelineno-16-17"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-16-18" name="__codelineno-16-18" href="#__codelineno-16-18"></a><span class="kd">func</span><span class="w"> </span><span class="nx">graphDFS</span><span class="p">(</span><span class="nx">g</span><span class="w"> </span><span class="o">*</span><span class="nx">graphAdjList</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="w"> </span><span class="nx">Vertex</span><span class="p">)</span><span class="w"> </span><span class="p">[]</span><span class="nx">Vertex</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-19" name="__codelineno-16-19" href="#__codelineno-16-19"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4186,7 +4186,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.swift</span><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.swift</span><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="kd">func</span> <span class="nf">dfs</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">visited</span><span class="p">:</span> <span class="kr">inout</span> <span class="n">Set</span><span class="p">&lt;</span><span class="n">Vertex</span><span class="p">&gt;,</span> <span class="n">res</span><span class="p">:</span> <span class="kr">inout</span> <span class="p">[</span><span class="n">Vertex</span><span class="p">],</span> <span class="n">vet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="n">res</span><span class="p">.</span><span class="n">append</span><span class="p">(</span><span class="n">vet</span><span class="p">)</span> <span class="c1">// 记录访问顶点</span>
<a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a> <span class="n">visited</span><span class="p">.</span><span class="bp">insert</span><span class="p">(</span><span class="n">vet</span><span class="p">)</span> <span class="c1">// 标记该顶点已被访问</span>
@@ -4200,7 +4200,7 @@
<a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a> <span class="p">}</span>
<a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a><span class="p">}</span>
<a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a>
<a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-17-16" name="__codelineno-17-16" href="#__codelineno-17-16"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-17-17" name="__codelineno-17-17" href="#__codelineno-17-17"></a><span class="kd">func</span> <span class="nf">graphDFS</span><span class="p">(</span><span class="n">graph</span><span class="p">:</span> <span class="n">GraphAdjList</span><span class="p">,</span> <span class="n">startVet</span><span class="p">:</span> <span class="n">Vertex</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="p">[</span><span class="n">Vertex</span><span class="p">]</span> <span class="p">{</span>
<a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a> <span class="c1">// 顶点遍历序列</span>
@@ -4213,7 +4213,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.js</span><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<div class="highlight"><span class="filename">graph_dfs.js</span><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="kd">function</span><span class="w"> </span><span class="nx">dfs</span><span class="p">(</span><span class="nx">graph</span><span class="p">,</span><span class="w"> </span><span class="nx">visited</span><span class="p">,</span><span class="w"> </span><span class="nx">res</span><span class="p">,</span><span class="w"> </span><span class="nx">vet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="w"> </span><span class="nx">res</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录访问顶点</span>
@@ -4228,7 +4228,7 @@
<a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a><span class="p">}</span>
<a id="__codelineno-18-15" name="__codelineno-18-15" href="#__codelineno-18-15"></a>
<a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-18-17" name="__codelineno-18-17" href="#__codelineno-18-17"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-18-18" name="__codelineno-18-18" href="#__codelineno-18-18"></a><span class="kd">function</span><span class="w"> </span><span class="nx">graphDFS</span><span class="p">(</span><span class="nx">graph</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-19" name="__codelineno-18-19" href="#__codelineno-18-19"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4241,7 +4241,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.ts</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.ts</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="kd">function</span><span class="w"> </span><span class="nx">dfs</span><span class="p">(</span>
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="nx">graph</span><span class="o">:</span><span class="w"> </span><span class="kt">GraphAdjList</span><span class="p">,</span>
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="w"> </span><span class="nx">visited</span><span class="o">:</span><span class="w"> </span><span class="kt">Set</span><span class="o">&lt;</span><span class="nx">Vertex</span><span class="o">&gt;</span><span class="p">,</span>
@@ -4260,7 +4260,7 @@
<a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a><span class="p">}</span>
<a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a>
<a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a><span class="kd">function</span><span class="w"> </span><span class="nx">graphDFS</span><span class="p">(</span><span class="nx">graph</span><span class="o">:</span><span class="w"> </span><span class="kt">GraphAdjList</span><span class="p">,</span><span class="w"> </span><span class="nx">startVet</span><span class="o">:</span><span class="w"> </span><span class="kt">Vertex</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nx">Vertex</span><span class="p">[]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4273,7 +4273,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.dart</span><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.dart</span><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="kt">void</span><span class="w"> </span><span class="n">dfs</span><span class="p">(</span>
<a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="w"> </span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span>
<a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="w"> </span><span class="n">Set</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">visited</span><span class="p">,</span>
@@ -4292,7 +4292,7 @@
<a id="__codelineno-20-17" name="__codelineno-20-17" href="#__codelineno-20-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-18" name="__codelineno-20-18" href="#__codelineno-20-18"></a><span class="p">}</span>
<a id="__codelineno-20-19" name="__codelineno-20-19" href="#__codelineno-20-19"></a>
<a id="__codelineno-20-20" name="__codelineno-20-20" href="#__codelineno-20-20"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-20-20" name="__codelineno-20-20" href="#__codelineno-20-20"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-20-21" name="__codelineno-20-21" href="#__codelineno-20-21"></a><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">graphDFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="n">startVet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-22" name="__codelineno-20-22" href="#__codelineno-20-22"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
<a id="__codelineno-20-23" name="__codelineno-20-23" href="#__codelineno-20-23"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
@@ -4304,7 +4304,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">graph_dfs.rs</span><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<div class="highlight"><span class="filename">graph_dfs.rs</span><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="k">fn</span> <span class="nf">dfs</span><span class="p">(</span><span class="n">graph</span>: <span class="kp">&amp;</span><span class="nc">GraphAdjList</span><span class="p">,</span><span class="w"> </span><span class="n">visited</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="n">HashSet</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">res</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="p">,</span><span class="w"> </span><span class="n">vet</span>: <span class="nc">Vertex</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="n">res</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 记录访问顶点</span>
<a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="w"> </span><span class="n">visited</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="n">vet</span><span class="p">);</span><span class="w"> </span><span class="c1">// 标记该顶点已被访问</span>
@@ -4320,7 +4320,7 @@
<a id="__codelineno-21-14" name="__codelineno-21-14" href="#__codelineno-21-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-15" name="__codelineno-21-15" href="#__codelineno-21-15"></a><span class="p">}</span>
<a id="__codelineno-21-16" name="__codelineno-21-16" href="#__codelineno-21-16"></a>
<a id="__codelineno-21-17" name="__codelineno-21-17" href="#__codelineno-21-17"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-21-17" name="__codelineno-21-17" href="#__codelineno-21-17"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-21-18" name="__codelineno-21-18" href="#__codelineno-21-18"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-21-19" name="__codelineno-21-19" href="#__codelineno-21-19"></a><span class="k">fn</span> <span class="nf">graph_dfs</span><span class="p">(</span><span class="n">graph</span>: <span class="nc">GraphAdjList</span><span class="p">,</span><span class="w"> </span><span class="n">start_vet</span>: <span class="nc">Vertex</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Vec</span><span class="o">&lt;</span><span class="n">Vertex</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-21-20" name="__codelineno-21-20" href="#__codelineno-21-20"></a><span class="w"> </span><span class="c1">// 顶点遍历序列</span>
@@ -4345,7 +4345,7 @@
<a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a><span class="p">}</span>
<a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a>
<a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a><span class="cm">/* 深度优先遍历 DFS 辅助函数 */</span>
<a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a><span class="cm">/* 深度优先遍历辅助函数 */</span>
<a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></a><span class="kt">void</span><span class="w"> </span><span class="nf">dfs</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">*</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">**</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">resSize</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">vet</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a><span class="w"> </span><span class="c1">// 记录访问顶点</span>
<a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a><span class="w"> </span><span class="n">res</span><span class="p">[(</span><span class="o">*</span><span class="n">resSize</span><span class="p">)</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">vet</span><span class="p">;</span>
@@ -4361,7 +4361,7 @@
<a id="__codelineno-22-25" name="__codelineno-22-25" href="#__codelineno-22-25"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-22-26" name="__codelineno-22-26" href="#__codelineno-22-26"></a><span class="p">}</span>
<a id="__codelineno-22-27" name="__codelineno-22-27" href="#__codelineno-22-27"></a>
<a id="__codelineno-22-28" name="__codelineno-22-28" href="#__codelineno-22-28"></a><span class="cm">/* 深度优先遍历 DFS */</span>
<a id="__codelineno-22-28" name="__codelineno-22-28" href="#__codelineno-22-28"></a><span class="cm">/* 深度优先遍历 */</span>
<a id="__codelineno-22-29" name="__codelineno-22-29" href="#__codelineno-22-29"></a><span class="c1">// 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点</span>
<a id="__codelineno-22-30" name="__codelineno-22-30" href="#__codelineno-22-30"></a><span class="kt">void</span><span class="w"> </span><span class="nf">graphDFS</span><span class="p">(</span><span class="n">GraphAdjList</span><span class="w"> </span><span class="o">*</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">*</span><span class="n">startVet</span><span class="p">,</span><span class="w"> </span><span class="n">Vertex</span><span class="w"> </span><span class="o">**</span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">resSize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-31" name="__codelineno-22-31" href="#__codelineno-22-31"></a><span class="w"> </span><span class="n">dfs</span><span class="p">(</span><span class="n">graph</span><span class="p">,</span><span class="w"> </span><span class="n">res</span><span class="p">,</span><span class="w"> </span><span class="n">resSize</span><span class="p">,</span><span class="w"> </span><span class="n">startVet</span><span class="p">);</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3966,13 +3966,13 @@
</div>
</div>
</div>
<p>在最差情况下,需要遍历整个物品列表,<strong>因此时间复杂度为 <span class="arithmatex">\(O(n)\)</span></strong> ,其中 <span class="arithmatex">\(n\)</span> 为物品数量。</p>
<p>除排序之外,在最差情况下,需要遍历整个物品列表,<strong>因此时间复杂度为 <span class="arithmatex">\(O(n)\)</span></strong> ,其中 <span class="arithmatex">\(n\)</span> 为物品数量。</p>
<p>由于初始化了一个 <code>Item</code> 对象列表,<strong>因此空间复杂度为 <span class="arithmatex">\(O(n)\)</span></strong></p>
<h3 id="3">3. &nbsp; 正确性证明<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>采用反证法。假设物品 <span class="arithmatex">\(x\)</span> 是单位价值最高的物品,使用某算法求得最大价值为 <code>res</code> ,但该解中不包含物品 <span class="arithmatex">\(x\)</span></p>
<p>现在从背包中拿出单位重量的任意物品,并替换为单位重量的物品 <span class="arithmatex">\(x\)</span> 。由于物品 <span class="arithmatex">\(x\)</span> 的单位价值最高,因此替换后的总价值一定大于 <code>res</code><strong>这与 <code>res</code> 是最优解矛盾,说明最优解中必须包含物品 <span class="arithmatex">\(x\)</span></strong></p>
<p>对于该解中的其他物品,我们也可以构建出上述矛盾。总而言之,<strong>单位价值更大的物品总是更优选择</strong>,这说明贪心策略是有效的。</p>
<p>如图 15-6 所示,如果将物品重量和物品单位价值分别看作一张二维图表的横轴和纵轴,则分数背包问题可转化为“求在有限横轴区间下的最大围成面积”。这个类比可以帮助我们从几何角度理解贪心策略的有效性。</p>
<p>如图 15-6 所示,如果将物品重量和物品单位价值分别看作一张二维图表的横轴和纵轴,则分数背包问题可转化为“求在有限横轴区间下围成的最大面积”。这个类比可以帮助我们从几何角度理解贪心策略的有效性。</p>
<p><a class="glightbox" href="../fractional_knapsack_problem.assets/fractional_knapsack_area_chart.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="分数背包问题的几何表示" class="animation-figure" src="../fractional_knapsack_problem.assets/fractional_knapsack_area_chart.png" /></a></p>
<p align="center"> 图 15-6 &nbsp; 分数背包问题的几何表示 </p>
+16 -15
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3125,7 +3125,7 @@
<li class="md-nav__item">
<a href="#1511" class="md-nav__link">
<span class="md-ellipsis">
15.1.1 &nbsp; 贪心的优点与局限性
15.1.1 &nbsp; 贪心算法的优点与局限性
</span>
</a>
@@ -3143,7 +3143,7 @@
<li class="md-nav__item">
<a href="#1513" class="md-nav__link">
<span class="md-ellipsis">
15.1.3 &nbsp; 贪心解题步骤
15.1.3 &nbsp; 贪心算法解题步骤
</span>
</a>
@@ -3152,7 +3152,7 @@
<li class="md-nav__item">
<a href="#1514" class="md-nav__link">
<span class="md-ellipsis">
15.1.4 &nbsp; 贪心典型例题
15.1.4 &nbsp; 贪心算法典型例题
</span>
</a>
@@ -3481,7 +3481,7 @@
<li class="md-nav__item">
<a href="#1511" class="md-nav__link">
<span class="md-ellipsis">
15.1.1 &nbsp; 贪心的优点与局限性
15.1.1 &nbsp; 贪心算法的优点与局限性
</span>
</a>
@@ -3499,7 +3499,7 @@
<li class="md-nav__item">
<a href="#1513" class="md-nav__link">
<span class="md-ellipsis">
15.1.3 &nbsp; 贪心解题步骤
15.1.3 &nbsp; 贪心算法解题步骤
</span>
</a>
@@ -3508,7 +3508,7 @@
<li class="md-nav__item">
<a href="#1514" class="md-nav__link">
<span class="md-ellipsis">
15.1.4 &nbsp; 贪心典型例题
15.1.4 &nbsp; 贪心算法典型例题
</span>
</a>
@@ -3560,13 +3560,13 @@
<p>我们先通过例题“零钱兑换”了解贪心算法的工作原理。这道题已经在“完全背包问题”章节中介绍过,相信你对它并不陌生。</p>
<div class="admonition question">
<p class="admonition-title">Question</p>
<p>给定 <span class="arithmatex">\(n\)</span> 种硬币,第 <span class="arithmatex">\(i\)</span> 种硬币的面值为 <span class="arithmatex">\(coins[i - 1]\)</span> ,目标金额为 <span class="arithmatex">\(amt\)</span> ,每种硬币可以重复选取,问能够凑出目标金额的最少硬币数量。如果无法凑出目标金额则返回 <span class="arithmatex">\(-1\)</span></p>
<p>给定 <span class="arithmatex">\(n\)</span> 种硬币,第 <span class="arithmatex">\(i\)</span> 种硬币的面值为 <span class="arithmatex">\(coins[i - 1]\)</span> ,目标金额为 <span class="arithmatex">\(amt\)</span> ,每种硬币可以重复选取,问能够凑出目标金额的最少硬币数量。如果无法凑出目标金额则返回 <span class="arithmatex">\(-1\)</span></p>
</div>
<p>本题采取的贪心策略如图 15-1 所示。给定目标金额,<strong>我们贪心地选择不大于且最接近它的硬币</strong>,不断循环该步骤,直至凑出目标金额为止。</p>
<p><a class="glightbox" href="../greedy_algorithm.assets/coin_change_greedy_strategy.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="零钱兑换的贪心策略" class="animation-figure" src="../greedy_algorithm.assets/coin_change_greedy_strategy.png" /></a></p>
<p align="center"> 图 15-1 &nbsp; 零钱兑换的贪心策略 </p>
<p>实现代码如下所示。你可能会不由地发出感叹:So clean !贪心算法仅用约十行代码就解决了零钱兑换问题</p>
<p>实现代码如下所示:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -3811,7 +3811,8 @@
</div>
</div>
</div>
<h2 id="1511">15.1.1 &nbsp; 贪心的优点与局限性<a class="headerlink" href="#1511" title="Permanent link">&para;</a></h2>
<p>你可能会不由地发出感叹:So clean !贪心算法仅用约十行代码就解决了零钱兑换问题。</p>
<h2 id="1511">15.1.1 &nbsp; 贪心算法的优点与局限性<a class="headerlink" href="#1511" title="Permanent link">&para;</a></h2>
<p><strong>贪心算法不仅操作直接、实现简单,而且通常效率也很高</strong>。在以上代码中,记硬币最小面值为 <span class="arithmatex">\(\min(coins)\)</span> ,则贪心选择最多循环 <span class="arithmatex">\(amt / \min(coins)\)</span> 次,时间复杂度为 <span class="arithmatex">\(O(amt / \min(coins))\)</span> 。这比动态规划解法的时间复杂度 <span class="arithmatex">\(O(n \times amt)\)</span> 提升了一个数量级。</p>
<p>然而,<strong>对于某些硬币面值组合,贪心算法并不能找到最优解</strong>。图 15-2 给出了两个示例。</p>
<ul>
@@ -3819,8 +3820,8 @@
<li><strong>反例 <span class="arithmatex">\(coins = [1, 20, 50]\)</span></strong>:假设 <span class="arithmatex">\(amt = 60\)</span> ,贪心算法只能找到 <span class="arithmatex">\(50 + 1 \times 10\)</span> 的兑换组合,共计 <span class="arithmatex">\(11\)</span> 枚硬币,但动态规划可以找到最优解 <span class="arithmatex">\(20 + 20 + 20\)</span> ,仅需 <span class="arithmatex">\(3\)</span> 枚硬币。</li>
<li><strong>反例 <span class="arithmatex">\(coins = [1, 49, 50]\)</span></strong>:假设 <span class="arithmatex">\(amt = 98\)</span> ,贪心算法只能找到 <span class="arithmatex">\(50 + 1 \times 48\)</span> 的兑换组合,共计 <span class="arithmatex">\(49\)</span> 枚硬币,但动态规划可以找到最优解 <span class="arithmatex">\(49 + 49\)</span> ,仅需 <span class="arithmatex">\(2\)</span> 枚硬币。</li>
</ul>
<p><a class="glightbox" href="../greedy_algorithm.assets/coin_change_greedy_vs_dp.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="贪心无法找出最优解的示例" class="animation-figure" src="../greedy_algorithm.assets/coin_change_greedy_vs_dp.png" /></a></p>
<p align="center"> 图 15-2 &nbsp; 贪心无法找出最优解的示例 </p>
<p><a class="glightbox" href="../greedy_algorithm.assets/coin_change_greedy_vs_dp.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="贪心算法无法找出最优解的示例" class="animation-figure" src="../greedy_algorithm.assets/coin_change_greedy_vs_dp.png" /></a></p>
<p align="center"> 图 15-2 &nbsp; 贪心算法无法找出最优解的示例 </p>
<p>也就是说,对于零钱兑换问题,贪心算法无法保证找到全局最优解,并且有可能找到非常差的解。它更适合用动态规划解决。</p>
<p>一般情况下,贪心算法的适用情况分以下两种。</p>
@@ -3841,9 +3842,9 @@
<div class="admonition quote">
<p class="admonition-title">Quote</p>
<p>有一篇论文给出了一个 <span class="arithmatex">\(O(n^3)\)</span> 时间复杂度的算法,用于判断一个硬币组合能否使用贪心算法找出任意金额的最优解。</p>
<p>Pearson, David. A polynomial-time algorithm for the change-making problem. Operations Research Letters 33.3 (2005): 231-234.</p>
<p>Pearson, D. A polynomial-time algorithm for the change-making problem[J]. Operations Research Letters, 2005, 33(3): 231-234.</p>
</div>
<h2 id="1513">15.1.3 &nbsp; 贪心解题步骤<a class="headerlink" href="#1513" title="Permanent link">&para;</a></h2>
<h2 id="1513">15.1.3 &nbsp; 贪心算法解题步骤<a class="headerlink" href="#1513" title="Permanent link">&para;</a></h2>
<p>贪心问题的解决流程大体可分为以下三步。</p>
<ol>
<li><strong>问题分析</strong>:梳理与理解问题特性,包括状态定义、优化目标和约束条件等。这一步在回溯和动态规划中都有涉及。</li>
@@ -3857,7 +3858,7 @@
</ul>
<p>为了保证正确性,我们应该对贪心策略进行严谨的数学证明,<strong>通常需要用到反证法或数学归纳法</strong></p>
<p>然而,正确性证明也很可能不是一件易事。如若没有头绪,我们通常会选择面向测试用例进行代码调试,一步步修改与验证贪心策略。</p>
<h2 id="1514">15.1.4 &nbsp; 贪心典型例题<a class="headerlink" href="#1514" title="Permanent link">&para;</a></h2>
<h2 id="1514">15.1.4 &nbsp; 贪心算法典型例题<a class="headerlink" href="#1514" title="Permanent link">&para;</a></h2>
<p>贪心算法常常应用在满足贪心选择性质和最优子结构的优化问题中,以下列举了一些典型的贪心算法问题。</p>
<ul>
<li><strong>硬币找零问题</strong>:在某些硬币组合下,贪心算法总是可以得到最优解。</li>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+14 -14
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3562,10 +3562,10 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<p><a class="glightbox" href="../max_capacity_problem.assets/max_capacity_moving_short_board.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="向内移动短板后的状态" class="animation-figure" src="../max_capacity_problem.assets/max_capacity_moving_short_board.png" /></a></p>
<p align="center"> 图 15-10 &nbsp; 向内移动短板后的状态 </p>
<p>由此便可推出本题的贪心策略:初始化两指针分列容器两端,每轮向内收缩短板对应的指针,直至两指针相遇。</p>
<p>由此便可推出本题的贪心策略:初始化两指针,使其分列容器两端,每轮向内收缩短板对应的指针,直至两指针相遇。</p>
<p>图 15-11 展示了贪心策略的执行过程。</p>
<ol>
<li>初始状态下,指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 分列数组两端。</li>
<li>初始状态下,指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 分列数组两端。</li>
<li>计算当前状态的容量 <span class="arithmatex">\(cap[i, j]\)</span> ,并更新最大容量。</li>
<li>比较板 <span class="arithmatex">\(i\)</span> 和 板 <span class="arithmatex">\(j\)</span> 的高度,并将短板向内移动一格。</li>
<li>循环执行第 <code>2.</code> 步和第 <code>3.</code> 步,直至 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 相遇时结束。</li>
@@ -3611,7 +3611,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.py</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="k">def</span> <span class="nf">max_capacity</span><span class="p">(</span><span class="n">ht</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">])</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;最大容量:贪心&quot;&quot;&quot;</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="c1"># 初始化 i, j 分列数组两端</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="c1"># 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="n">i</span><span class="p">,</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">ht</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="c1"># 初始最大容量为 0</span>
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="n">res</span> <span class="o">=</span> <span class="mi">0</span>
@@ -3631,7 +3631,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.cpp</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">maxCapacity</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">ht</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ht</span><span class="p">.</span><span class="n">size</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
@@ -3654,7 +3654,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.java</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">maxCapacity</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">ht</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ht</span><span class="p">.</span><span class="na">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
@@ -3677,7 +3677,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.cs</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">MaxCapacity</span><span class="p">(</span><span class="kt">int</span><span class="p">[]</span><span class="w"> </span><span class="n">ht</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ht</span><span class="p">.</span><span class="n">Length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span>
@@ -3700,7 +3700,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.go</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="kd">func</span><span class="w"> </span><span class="nx">maxCapacity</span><span class="p">(</span><span class="nx">ht</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w"> </span><span class="nb">len</span><span class="p">(</span><span class="nx">ht</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span>
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="w"> </span><span class="nx">res</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span>
@@ -3723,7 +3723,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.swift</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="kd">func</span> <span class="nf">maxCapacity</span><span class="p">(</span><span class="n">ht</span><span class="p">:</span> <span class="p">[</span><span class="nb">Int</span><span class="p">])</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> <span class="kd">var</span> <span class="nv">i</span> <span class="p">=</span> <span class="mi">0</span><span class="p">,</span> <span class="n">j</span> <span class="p">=</span> <span class="n">ht</span><span class="p">.</span><span class="bp">count</span> <span class="o">-</span> <span class="mi">1</span>
<a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> <span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="kd">var</span> <span class="nv">res</span> <span class="p">=</span> <span class="mi">0</span>
@@ -3746,7 +3746,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.js</span><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="kd">function</span><span class="w"> </span><span class="nx">maxCapacity</span><span class="p">(</span><span class="nx">ht</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
<a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ht</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
@@ -3770,7 +3770,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.ts</span><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="kd">function</span><span class="w"> </span><span class="nx">maxCapacity</span><span class="p">(</span><span class="nx">ht</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">[])</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">ht</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
@@ -3794,7 +3794,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.dart</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="kt">int</span><span class="w"> </span><span class="n">maxCapacity</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">ht</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ht</span><span class="p">.</span><span class="n">length</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">res</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span>
@@ -3817,7 +3817,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.rs</span><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="k">fn</span> <span class="nf">max_capacity</span><span class="p">(</span><span class="n">ht</span>: <span class="kp">&amp;</span><span class="p">[</span><span class="kt">i32</span><span class="p">])</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span>
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ht</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
@@ -3841,7 +3841,7 @@ cap[i, j] = \min(ht[i], ht[j]) \times (j - i)
<div class="tabbed-block">
<div class="highlight"><span class="filename">max_capacity.c</span><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="cm">/* 最大容量:贪心 */</span>
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">maxCapacity</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">ht</span><span class="p">[],</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">htLength</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j 分列数组两端</span>
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="c1">// 初始化 i, j,使其分列数组两端</span>
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">htLength</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="w"> </span><span class="c1">// 初始最大容量为 0</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3573,7 +3573,7 @@ n &amp; \geq 4
<ol>
<li>输入整数 <span class="arithmatex">\(n\)</span> ,从其不断地切分出因子 <span class="arithmatex">\(3\)</span> ,直至余数为 <span class="arithmatex">\(0\)</span><span class="arithmatex">\(1\)</span><span class="arithmatex">\(2\)</span></li>
<li>当余数为 <span class="arithmatex">\(0\)</span> 时,代表 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(3\)</span> 的倍数,因此不做任何处理。</li>
<li>当余数为 <span class="arithmatex">\(2\)</span> 时,不继续划分,保留</li>
<li>当余数为 <span class="arithmatex">\(2\)</span> 时,不继续划分,保留。</li>
<li>当余数为 <span class="arithmatex">\(1\)</span> 时,由于 <span class="arithmatex">\(2 \times 2 &gt; 1 \times 3\)</span> ,因此应将最后一个 <span class="arithmatex">\(3\)</span> 替换为 <span class="arithmatex">\(2\)</span></li>
</ol>
<h3 id="2">2. &nbsp; 代码实现<a class="headerlink" href="#2" title="Permanent link">&para;</a></h3>
+2 -2
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3451,7 +3451,7 @@
<li>求解贪心问题主要分为三步:问题分析、确定贪心策略、正确性证明。其中,确定贪心策略是核心步骤,正确性证明往往是难点。</li>
<li>分数背包问题在 0-1 背包的基础上,允许选择物品的一部分,因此可使用贪心算法求解。贪心策略的正确性可以使用反证法来证明。</li>
<li>最大容量问题可使用穷举法求解,时间复杂度为 <span class="arithmatex">\(O(n^2)\)</span> 。通过设计贪心策略,每轮向内移动短板,可将时间复杂度优化至 <span class="arithmatex">\(O(n)\)</span></li>
<li>在最大切分乘积问题中,我们先后推理出两个贪心策略:<span class="arithmatex">\(\geq 4\)</span> 的整数都应该继续切分最优切分因子为 <span class="arithmatex">\(3\)</span> 。代码中包含幂运算,时间复杂度取决于幂运算实现方法,通常为 <span class="arithmatex">\(O(1)\)</span><span class="arithmatex">\(O(\log n)\)</span></li>
<li>在最大切分乘积问题中,我们先后推理出两个贪心策略:<span class="arithmatex">\(\geq 4\)</span> 的整数都应该继续切分最优切分因子为 <span class="arithmatex">\(3\)</span> 。代码中包含幂运算,时间复杂度取决于幂运算实现方法,通常为 <span class="arithmatex">\(O(1)\)</span><span class="arithmatex">\(O(\log n)\)</span></li>
</ul>
<!-- Source file information -->
+7 -7
View File
@@ -1797,7 +1797,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4104,7 +4104,7 @@
<p>总而言之,我们通常选取质数作为模数,并且这个质数最好足够大,以尽可能消除周期性模式,提升哈希算法的稳健性。</p>
<h2 id="633">6.3.3 &nbsp; 常见哈希算法<a class="headerlink" href="#633" title="Permanent link">&para;</a></h2>
<p>不难发现,以上介绍的简单哈希算法都比较“脆弱”,远远没有达到哈希算法的设计目标。例如,由于加法和异或满足交换律,因此加法哈希和异或哈希无法区分内容相同但顺序不同的字符串,这可能会加剧哈希冲突,并引起一些安全问题。</p>
<p>在实际中,我们通常会用一些标准哈希算法,例如 MD5、SHA-1、SHA-2SHA-3 等。它们可以将任意长度的输入数据映射到恒定长度的哈希值。</p>
<p>在实际中,我们通常会用一些标准哈希算法,例如 MD5、SHA-1、SHA-2SHA-3 等。它们可以将任意长度的输入数据映射到恒定长度的哈希值。</p>
<p>近一个世纪以来,哈希算法处在不断升级与优化的过程中。一部分研究人员努力提升哈希算法的性能,另一部分研究人员和黑客则致力于寻找哈希算法的安全性问题。表 6-2 展示了在实际应用中常见的哈希算法。</p>
<ul>
<li>MD5 和 SHA-1 已多次被成功攻击,因此它们被各类安全应用弃用。</li>
@@ -4134,10 +4134,10 @@
</tr>
<tr>
<td>输出长度</td>
<td>128 bits</td>
<td>160 bits</td>
<td>256/512 bits</td>
<td>224/256/384/512 bits</td>
<td>128 bit</td>
<td>160 bit</td>
<td>256/512 bit</td>
<td>224/256/384/512 bit</td>
</tr>
<tr>
<td>哈希冲突</td>
@@ -4394,7 +4394,7 @@
</div>
<p>在许多编程语言中,<strong>只有不可变对象才可作为哈希表的 <code>key</code></strong> 。假如我们将列表(动态数组)作为 <code>key</code> ,当列表的内容发生变化时,它的哈希值也随之改变,我们就无法在哈希表中查询到原先的 <code>value</code> 了。</p>
<p>虽然自定义对象(比如链表节点)的成员变量是可变的,但它是可哈希的。<strong>这是因为对象的哈希值通常是基于内存地址生成的</strong>,即使对象的内容发生了变化,但它的内存地址不变,哈希值仍然是不变的。</p>
<p>细心的你可能发现在不同控制台中运行程序时,输出的哈希值是不同的。<strong>这是因为 Python 解释器在每次启动时,都会为字符串哈希函数加入一个随机的盐(Salt)值</strong>。这种做法可以有效防止 HashDoS 攻击,提升哈希算法的安全性。</p>
<p>细心的你可能发现在不同控制台中运行程序时,输出的哈希值是不同的。<strong>这是因为 Python 解释器在每次启动时,都会为字符串哈希函数加入一个随机的盐(salt)值</strong>。这种做法可以有效防止 HashDoS 攻击,提升哈希算法的安全性。</p>
<!-- Source file information -->
+70 -70
View File
@@ -1821,7 +1821,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3600,7 +3600,7 @@
<!-- Page content -->
<h1 id="62">6.2 &nbsp; 哈希冲突<a class="headerlink" href="#62" title="Permanent link">&para;</a></h1>
<p>上一节提到,<strong>通常情况下哈希函数的输入空间远大于输出空间</strong>,因此理论上哈希冲突是不可避免的。比如,输入空间为全体整数,输出空间为数组容量大小,则必然有多个整数映射至同一桶索引。</p>
<p>哈希冲突会导致查询结果错误,严重影响哈希表的可用性。为解决该问题,我们可以每当遇到哈希冲突就进行哈希表扩容,直至冲突消失为止。此方法简单粗暴且有效,但效率太低,因为哈希表扩容需要进行大量的数据搬运与哈希值计算。为了提升效率,我们可以采用以下策略。</p>
<p>哈希冲突会导致查询结果错误,严重影响哈希表的可用性。为解决该问题,每当遇到哈希冲突时,我们就进行哈希表扩容,直至冲突消失为止。此方法简单粗暴且有效,但效率太低,因为哈希表扩容需要进行大量的数据搬运与哈希值计算。为了提升效率,我们可以采用以下策略。</p>
<ol>
<li>改良哈希表数据结构,<strong>使得哈希表可以在出现哈希冲突时正常工作</strong></li>
<li>仅在必要时,即当哈希冲突比较严重时,才执行扩容操作。</li>
@@ -3619,8 +3619,8 @@
</ul>
<p>链式地址存在以下局限性。</p>
<ul>
<li><strong>占用空间增大</strong>链表包含节点指针,它相比数组更加耗费内存空间。</li>
<li><strong>查询效率降低</strong>因为需要线性遍历链表来查找对应元素。</li>
<li><strong>占用空间增大</strong>链表包含节点指针,它相比数组更加耗费内存空间。</li>
<li><strong>查询效率降低</strong>因为需要线性遍历链表来查找对应元素。</li>
</ul>
<p>以下代码给出了链式地址哈希表的简单实现,需要注意两点。</p>
<ul>
@@ -3653,11 +3653,11 @@
<a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;查询操作&quot;&quot;&quot;</span>
<a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a> <span class="n">index</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">hash_func</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
<a id="__codelineno-0-23" name="__codelineno-0-23" href="#__codelineno-0-23"></a> <span class="n">bucket</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-0-24" name="__codelineno-0-24" href="#__codelineno-0-24"></a> <span class="c1"># 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-0-24" name="__codelineno-0-24" href="#__codelineno-0-24"></a> <span class="c1"># 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-0-25" name="__codelineno-0-25" href="#__codelineno-0-25"></a> <span class="k">for</span> <span class="n">pair</span> <span class="ow">in</span> <span class="n">bucket</span><span class="p">:</span>
<a id="__codelineno-0-26" name="__codelineno-0-26" href="#__codelineno-0-26"></a> <span class="k">if</span> <span class="n">pair</span><span class="o">.</span><span class="n">key</span> <span class="o">==</span> <span class="n">key</span><span class="p">:</span>
<a id="__codelineno-0-27" name="__codelineno-0-27" href="#__codelineno-0-27"></a> <span class="k">return</span> <span class="n">pair</span><span class="o">.</span><span class="n">val</span>
<a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a> <span class="c1"># 若未找到 key 则返回 None</span>
<a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a> <span class="c1"># 若未找到 key 则返回 None</span>
<a id="__codelineno-0-29" name="__codelineno-0-29" href="#__codelineno-0-29"></a> <span class="k">return</span> <span class="kc">None</span>
<a id="__codelineno-0-30" name="__codelineno-0-30" href="#__codelineno-0-30"></a>
<a id="__codelineno-0-31" name="__codelineno-0-31" href="#__codelineno-0-31"></a> <span class="k">def</span> <span class="nf">put</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
@@ -3749,13 +3749,13 @@
<a id="__codelineno-1-36" name="__codelineno-1-36" href="#__codelineno-1-36"></a><span class="w"> </span><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-1-37" name="__codelineno-1-37" href="#__codelineno-1-37"></a><span class="w"> </span><span class="n">string</span><span class="w"> </span><span class="n">get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-38" name="__codelineno-1-38" href="#__codelineno-1-38"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-1-39" name="__codelineno-1-39" href="#__codelineno-1-39"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-1-39" name="__codelineno-1-39" href="#__codelineno-1-39"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-1-40" name="__codelineno-1-40" href="#__codelineno-1-40"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">Pair</span><span class="w"> </span><span class="o">*</span><span class="n">pair</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-41" name="__codelineno-1-41" href="#__codelineno-1-41"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pair</span><span class="o">-&gt;</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-42" name="__codelineno-1-42" href="#__codelineno-1-42"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pair</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">;</span>
<a id="__codelineno-1-43" name="__codelineno-1-43" href="#__codelineno-1-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-1-44" name="__codelineno-1-44" href="#__codelineno-1-44"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-1-45" name="__codelineno-1-45" href="#__codelineno-1-45"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-1-45" name="__codelineno-1-45" href="#__codelineno-1-45"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-1-46" name="__codelineno-1-46" href="#__codelineno-1-46"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="p">;</span>
<a id="__codelineno-1-47" name="__codelineno-1-47" href="#__codelineno-1-47"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-1-48" name="__codelineno-1-48" href="#__codelineno-1-48"></a>
@@ -3861,13 +3861,13 @@
<a id="__codelineno-2-32" name="__codelineno-2-32" href="#__codelineno-2-32"></a><span class="w"> </span><span class="n">String</span><span class="w"> </span><span class="nf">get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-33" name="__codelineno-2-33" href="#__codelineno-2-33"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-2-34" name="__codelineno-2-34" href="#__codelineno-2-34"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">Pair</span><span class="o">&gt;</span><span class="w"> </span><span class="n">bucket</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buckets</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="n">index</span><span class="p">);</span>
<a id="__codelineno-2-35" name="__codelineno-2-35" href="#__codelineno-2-35"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-2-35" name="__codelineno-2-35" href="#__codelineno-2-35"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-2-36" name="__codelineno-2-36" href="#__codelineno-2-36"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">Pair</span><span class="w"> </span><span class="n">pair</span><span class="w"> </span><span class="p">:</span><span class="w"> </span><span class="n">bucket</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-37" name="__codelineno-2-37" href="#__codelineno-2-37"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pair</span><span class="p">.</span><span class="na">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-38" name="__codelineno-2-38" href="#__codelineno-2-38"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pair</span><span class="p">.</span><span class="na">val</span><span class="p">;</span>
<a id="__codelineno-2-39" name="__codelineno-2-39" href="#__codelineno-2-39"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-2-40" name="__codelineno-2-40" href="#__codelineno-2-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-2-41" name="__codelineno-2-41" href="#__codelineno-2-41"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-2-41" name="__codelineno-2-41" href="#__codelineno-2-41"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-2-42" name="__codelineno-2-42" href="#__codelineno-2-42"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-2-43" name="__codelineno-2-43" href="#__codelineno-2-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-2-44" name="__codelineno-2-44" href="#__codelineno-2-44"></a>
@@ -3972,13 +3972,13 @@
<a id="__codelineno-3-31" name="__codelineno-3-31" href="#__codelineno-3-31"></a><span class="w"> </span><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-3-32" name="__codelineno-3-32" href="#__codelineno-3-32"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="kt">string?</span><span class="w"> </span><span class="n">Get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-33" name="__codelineno-3-33" href="#__codelineno-3-33"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-3-34" name="__codelineno-3-34" href="#__codelineno-3-34"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-3-34" name="__codelineno-3-34" href="#__codelineno-3-34"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-3-35" name="__codelineno-3-35" href="#__codelineno-3-35"></a><span class="w"> </span><span class="k">foreach</span><span class="w"> </span><span class="p">(</span><span class="n">Pair</span><span class="w"> </span><span class="n">pair</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-36" name="__codelineno-3-36" href="#__codelineno-3-36"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-37" name="__codelineno-3-37" href="#__codelineno-3-37"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="p">;</span>
<a id="__codelineno-3-38" name="__codelineno-3-38" href="#__codelineno-3-38"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-3-39" name="__codelineno-3-39" href="#__codelineno-3-39"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-3-40" name="__codelineno-3-40" href="#__codelineno-3-40"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-3-40" name="__codelineno-3-40" href="#__codelineno-3-40"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-3-41" name="__codelineno-3-41" href="#__codelineno-3-41"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">null</span><span class="p">;</span>
<a id="__codelineno-3-42" name="__codelineno-3-42" href="#__codelineno-3-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-3-43" name="__codelineno-3-43" href="#__codelineno-3-43"></a>
@@ -4087,13 +4087,13 @@
<a id="__codelineno-4-36" name="__codelineno-4-36" href="#__codelineno-4-36"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">m</span><span class="w"> </span><span class="o">*</span><span class="nx">hashMapChaining</span><span class="p">)</span><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-37" name="__codelineno-4-37" href="#__codelineno-4-37"></a><span class="w"> </span><span class="nx">idx</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">hashFunc</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span>
<a id="__codelineno-4-38" name="__codelineno-4-38" href="#__codelineno-4-38"></a><span class="w"> </span><span class="nx">bucket</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">idx</span><span class="p">]</span>
<a id="__codelineno-4-39" name="__codelineno-4-39" href="#__codelineno-4-39"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-4-39" name="__codelineno-4-39" href="#__codelineno-4-39"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-4-40" name="__codelineno-4-40" href="#__codelineno-4-40"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">p</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="k">range</span><span class="w"> </span><span class="nx">bucket</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-41" name="__codelineno-4-41" href="#__codelineno-4-41"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">key</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-42" name="__codelineno-4-42" href="#__codelineno-4-42"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">p</span><span class="p">.</span><span class="nx">val</span>
<a id="__codelineno-4-43" name="__codelineno-4-43" href="#__codelineno-4-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-4-44" name="__codelineno-4-44" href="#__codelineno-4-44"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&quot;&quot;</span>
<a id="__codelineno-4-47" name="__codelineno-4-47" href="#__codelineno-4-47"></a><span class="p">}</span>
<a id="__codelineno-4-48" name="__codelineno-4-48" href="#__codelineno-4-48"></a>
@@ -4205,13 +4205,13 @@
<a id="__codelineno-5-29" name="__codelineno-5-29" href="#__codelineno-5-29"></a> <span class="kd">func</span> <span class="nf">get</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">String</span><span class="p">?</span> <span class="p">{</span>
<a id="__codelineno-5-30" name="__codelineno-5-30" href="#__codelineno-5-30"></a> <span class="kd">let</span> <span class="nv">index</span> <span class="p">=</span> <span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">:</span> <span class="n">key</span><span class="p">)</span>
<a id="__codelineno-5-31" name="__codelineno-5-31" href="#__codelineno-5-31"></a> <span class="kd">let</span> <span class="nv">bucket</span> <span class="p">=</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-5-32" name="__codelineno-5-32" href="#__codelineno-5-32"></a> <span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-5-32" name="__codelineno-5-32" href="#__codelineno-5-32"></a> <span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-5-33" name="__codelineno-5-33" href="#__codelineno-5-33"></a> <span class="k">for</span> <span class="n">pair</span> <span class="k">in</span> <span class="n">bucket</span> <span class="p">{</span>
<a id="__codelineno-5-34" name="__codelineno-5-34" href="#__codelineno-5-34"></a> <span class="k">if</span> <span class="n">pair</span><span class="p">.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-5-35" name="__codelineno-5-35" href="#__codelineno-5-35"></a> <span class="k">return</span> <span class="n">pair</span><span class="p">.</span><span class="n">val</span>
<a id="__codelineno-5-36" name="__codelineno-5-36" href="#__codelineno-5-36"></a> <span class="p">}</span>
<a id="__codelineno-5-37" name="__codelineno-5-37" href="#__codelineno-5-37"></a> <span class="p">}</span>
<a id="__codelineno-5-38" name="__codelineno-5-38" href="#__codelineno-5-38"></a> <span class="c1">// 若未找到 key 则返回 nil</span>
<a id="__codelineno-5-38" name="__codelineno-5-38" href="#__codelineno-5-38"></a> <span class="c1">// 若未找到 key 则返回 nil</span>
<a id="__codelineno-5-39" name="__codelineno-5-39" href="#__codelineno-5-39"></a> <span class="k">return</span> <span class="kc">nil</span>
<a id="__codelineno-5-40" name="__codelineno-5-40" href="#__codelineno-5-40"></a> <span class="p">}</span>
<a id="__codelineno-5-41" name="__codelineno-5-41" href="#__codelineno-5-41"></a>
@@ -4307,13 +4307,13 @@
<a id="__codelineno-6-29" name="__codelineno-6-29" href="#__codelineno-6-29"></a><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-30" name="__codelineno-6-30" href="#__codelineno-6-30"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">hashFunc</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
<a id="__codelineno-6-31" name="__codelineno-6-31" href="#__codelineno-6-31"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">bucket</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-6-32" name="__codelineno-6-32" href="#__codelineno-6-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-6-32" name="__codelineno-6-32" href="#__codelineno-6-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-6-33" name="__codelineno-6-33" href="#__codelineno-6-33"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">pair</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">bucket</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-34" name="__codelineno-6-34" href="#__codelineno-6-34"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pair</span><span class="p">.</span><span class="nx">key</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-35" name="__codelineno-6-35" href="#__codelineno-6-35"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">pair</span><span class="p">.</span><span class="nx">val</span><span class="p">;</span>
<a id="__codelineno-6-36" name="__codelineno-6-36" href="#__codelineno-6-36"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-6-37" name="__codelineno-6-37" href="#__codelineno-6-37"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-6-38" name="__codelineno-6-38" href="#__codelineno-6-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-6-38" name="__codelineno-6-38" href="#__codelineno-6-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-6-39" name="__codelineno-6-39" href="#__codelineno-6-39"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-6-40" name="__codelineno-6-40" href="#__codelineno-6-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-6-41" name="__codelineno-6-41" href="#__codelineno-6-41"></a>
@@ -4413,13 +4413,13 @@
<a id="__codelineno-7-29" name="__codelineno-7-29" href="#__codelineno-7-29"></a><span class="w"> </span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-30" name="__codelineno-7-30" href="#__codelineno-7-30"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">hashFunc</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
<a id="__codelineno-7-31" name="__codelineno-7-31" href="#__codelineno-7-31"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">bucket</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-7-32" name="__codelineno-7-32" href="#__codelineno-7-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-7-32" name="__codelineno-7-32" href="#__codelineno-7-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-7-33" name="__codelineno-7-33" href="#__codelineno-7-33"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">pair</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">bucket</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-34" name="__codelineno-7-34" href="#__codelineno-7-34"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">pair</span><span class="p">.</span><span class="nx">key</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-35" name="__codelineno-7-35" href="#__codelineno-7-35"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">pair</span><span class="p">.</span><span class="nx">val</span><span class="p">;</span>
<a id="__codelineno-7-36" name="__codelineno-7-36" href="#__codelineno-7-36"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-7-37" name="__codelineno-7-37" href="#__codelineno-7-37"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-7-38" name="__codelineno-7-38" href="#__codelineno-7-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-7-38" name="__codelineno-7-38" href="#__codelineno-7-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-7-39" name="__codelineno-7-39" href="#__codelineno-7-39"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-7-40" name="__codelineno-7-40" href="#__codelineno-7-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-7-41" name="__codelineno-7-41" href="#__codelineno-7-41"></a>
@@ -4519,13 +4519,13 @@
<a id="__codelineno-8-29" name="__codelineno-8-29" href="#__codelineno-8-29"></a><span class="w"> </span><span class="kt">String</span><span class="o">?</span><span class="w"> </span><span class="kd">get</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-30" name="__codelineno-8-30" href="#__codelineno-8-30"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashFunc</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-8-31" name="__codelineno-8-31" href="#__codelineno-8-31"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="n">Pair</span><span class="o">&gt;</span><span class="w"> </span><span class="n">bucket</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-8-32" name="__codelineno-8-32" href="#__codelineno-8-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-8-32" name="__codelineno-8-32" href="#__codelineno-8-32"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-8-33" name="__codelineno-8-33" href="#__codelineno-8-33"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">Pair</span><span class="w"> </span><span class="n">pair</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">bucket</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-34" name="__codelineno-8-34" href="#__codelineno-8-34"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-35" name="__codelineno-8-35" href="#__codelineno-8-35"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="p">;</span>
<a id="__codelineno-8-36" name="__codelineno-8-36" href="#__codelineno-8-36"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-8-37" name="__codelineno-8-37" href="#__codelineno-8-37"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-8-38" name="__codelineno-8-38" href="#__codelineno-8-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-8-38" name="__codelineno-8-38" href="#__codelineno-8-38"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 null</span>
<a id="__codelineno-8-39" name="__codelineno-8-39" href="#__codelineno-8-39"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-8-40" name="__codelineno-8-40" href="#__codelineno-8-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-8-41" name="__codelineno-8-41" href="#__codelineno-8-41"></a>
@@ -4639,7 +4639,7 @@
<a id="__codelineno-9-43" name="__codelineno-9-43" href="#__codelineno-9-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-44" name="__codelineno-9-44" href="#__codelineno-9-44"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-45" name="__codelineno-9-45" href="#__codelineno-9-45"></a>
<a id="__codelineno-9-46" name="__codelineno-9-46" href="#__codelineno-9-46"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 None</span>
<a id="__codelineno-9-46" name="__codelineno-9-46" href="#__codelineno-9-46"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 None</span>
<a id="__codelineno-9-47" name="__codelineno-9-47" href="#__codelineno-9-47"></a><span class="w"> </span><span class="nb">None</span>
<a id="__codelineno-9-48" name="__codelineno-9-48" href="#__codelineno-9-48"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-49" name="__codelineno-9-49" href="#__codelineno-9-49"></a>
@@ -4705,14 +4705,14 @@
<a id="__codelineno-9-109" name="__codelineno-9-109" href="#__codelineno-9-109"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">hash_func</span><span class="p">(</span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-9-110" name="__codelineno-9-110" href="#__codelineno-9-110"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">bucket</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="bp">self</span><span class="p">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-9-111" name="__codelineno-9-111" href="#__codelineno-9-111"></a>
<a id="__codelineno-9-112" name="__codelineno-9-112" href="#__codelineno-9-112"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-9-112" name="__codelineno-9-112" href="#__codelineno-9-112"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-9-113" name="__codelineno-9-113" href="#__codelineno-9-113"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">pair</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">bucket</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-114" name="__codelineno-9-114" href="#__codelineno-9-114"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">pair</span><span class="p">.</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-115" name="__codelineno-9-115" href="#__codelineno-9-115"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="o">&amp;</span><span class="n">pair</span><span class="p">.</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-9-116" name="__codelineno-9-116" href="#__codelineno-9-116"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-117" name="__codelineno-9-117" href="#__codelineno-9-117"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-118" name="__codelineno-9-118" href="#__codelineno-9-118"></a>
<a id="__codelineno-9-119" name="__codelineno-9-119" href="#__codelineno-9-119"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 None</span>
<a id="__codelineno-9-119" name="__codelineno-9-119" href="#__codelineno-9-119"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回 None</span>
<a id="__codelineno-9-120" name="__codelineno-9-120" href="#__codelineno-9-120"></a><span class="w"> </span><span class="nb">None</span>
<a id="__codelineno-9-121" name="__codelineno-9-121" href="#__codelineno-9-121"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-9-122" name="__codelineno-9-122" href="#__codelineno-9-122"></a><span class="p">}</span>
@@ -4776,7 +4776,7 @@
<a id="__codelineno-10-55" name="__codelineno-10-55" href="#__codelineno-10-55"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-10-56" name="__codelineno-10-56" href="#__codelineno-10-56"></a><span class="kt">char</span><span class="w"> </span><span class="o">*</span><span class="nf">get</span><span class="p">(</span><span class="n">HashMapChaining</span><span class="w"> </span><span class="o">*</span><span class="n">hashMap</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-57" name="__codelineno-10-57" href="#__codelineno-10-57"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashFunc</span><span class="p">(</span><span class="n">hashMap</span><span class="p">,</span><span class="w"> </span><span class="n">key</span><span class="p">);</span>
<a id="__codelineno-10-58" name="__codelineno-10-58" href="#__codelineno-10-58"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-10-58" name="__codelineno-10-58" href="#__codelineno-10-58"></a><span class="w"> </span><span class="c1">// 遍历桶,若找到 key 则返回对应 val</span>
<a id="__codelineno-10-59" name="__codelineno-10-59" href="#__codelineno-10-59"></a><span class="w"> </span><span class="n">Node</span><span class="w"> </span><span class="o">*</span><span class="n">cur</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-10-60" name="__codelineno-10-60" href="#__codelineno-10-60"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">cur</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-61" name="__codelineno-10-61" href="#__codelineno-10-61"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">cur</span><span class="o">-&gt;</span><span class="n">pair</span><span class="o">-&gt;</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4784,7 +4784,7 @@
<a id="__codelineno-10-63" name="__codelineno-10-63" href="#__codelineno-10-63"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-10-64" name="__codelineno-10-64" href="#__codelineno-10-64"></a><span class="w"> </span><span class="n">cur</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">cur</span><span class="o">-&gt;</span><span class="n">next</span><span class="p">;</span>
<a id="__codelineno-10-65" name="__codelineno-10-65" href="#__codelineno-10-65"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-10-66" name="__codelineno-10-66" href="#__codelineno-10-66"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="p">;</span><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-10-66" name="__codelineno-10-66" href="#__codelineno-10-66"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&quot;&quot;</span><span class="p">;</span><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-10-67" name="__codelineno-10-67" href="#__codelineno-10-67"></a><span class="p">}</span>
<a id="__codelineno-10-68" name="__codelineno-10-68" href="#__codelineno-10-68"></a>
<a id="__codelineno-10-69" name="__codelineno-10-69" href="#__codelineno-10-69"></a><span class="cm">/* 添加操作 */</span>
@@ -4888,24 +4888,24 @@
</div>
<p>值得注意的是,当链表很长时,查询效率 <span class="arithmatex">\(O(n)\)</span> 很差。<strong>此时可以将链表转换为“AVL 树”或“红黑树”</strong>,从而将查询操作的时间复杂度优化至 <span class="arithmatex">\(O(\log n)\)</span></p>
<h2 id="622">6.2.2 &nbsp; 开放寻址<a class="headerlink" href="#622" title="Permanent link">&para;</a></h2>
<p>「开放寻址 open addressing」不引入额外的数据结构,而是通过“多次探测”来处理哈希冲突,探测方式主要包括线性探测、平方探测多次哈希等。</p>
<p>「开放寻址 open addressing」不引入额外的数据结构,而是通过“多次探测”来处理哈希冲突,探测方式主要包括线性探测、平方探测多次哈希等。</p>
<p>下面以线性探测为例,介绍开放寻址哈希表的工作机制。</p>
<h3 id="1">1. &nbsp; 线性探测<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
<p>线性探测采用固定步长的线性搜索来进行探测,其操作方法与普通哈希表有所不同。</p>
<ul>
<li><strong>插入元素</strong>:通过哈希函数计算桶索引,若发现桶内已有元素,则从冲突位置向后线性遍历(步长通常为 <span class="arithmatex">\(1\)</span> ),直至找到空桶,将元素插入其中。</li>
<li><strong>查找元素</strong>:若发现哈希冲突,则使用相同步长向后线性遍历,直到找到对应元素,返回 <code>value</code> 即可;如果遇到空桶,说明目标元素不在哈希表中,返回 <span class="arithmatex">\(\text{None}\)</span></li>
<li><strong>查找元素</strong>:若发现哈希冲突,则使用相同步长向后进行线性遍历,直到找到对应元素,返回 <code>value</code> 即可;如果遇到空桶,说明目标元素不在哈希表中,返回 <code>None</code></li>
</ul>
<p>图 6-6 展示了开放寻址(线性探测)哈希表的键值对分布。根据此哈希函数,最后两位相同的 <code>key</code> 都会被映射到相同的桶。而通过线性探测,它们被依次存储在该桶以及之下的桶中。</p>
<p><a class="glightbox" href="../hash_collision.assets/hash_table_linear_probing.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="开放寻址线性探测" class="animation-figure" src="../hash_collision.assets/hash_table_linear_probing.png" /></a></p>
<p align="center"> 图 6-6 &nbsp; 开放寻址线性探测 </p>
<p><a class="glightbox" href="../hash_collision.assets/hash_table_linear_probing.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="开放寻址线性探测)哈希表的键值对分布" class="animation-figure" src="../hash_collision.assets/hash_table_linear_probing.png" /></a></p>
<p align="center"> 图 6-6 &nbsp; 开放寻址线性探测)哈希表的键值对分布 </p>
<p>然而,<strong>线性探测容易产生“聚集现象”</strong>。具体来说,数组中连续被占用的位置越长,这些连续位置发生哈希冲突的可能性越大,从而进一步促使该位置的聚堆生长,形成恶性循环,最终导致增删查改操作效率劣化。</p>
<p>值得注意的是,<strong>我们不能在开放寻址哈希表中直接删除元素</strong>。这是因为删除元素会在数组内产生一个空桶 <span class="arithmatex">\(\text{None}\)</span> ,而当查询元素时,线性探测到该空桶就会返回,因此在该空桶之下的元素都无法再被访问到,程序可能误判这些元素不存在。</p>
<p>值得注意的是,<strong>我们不能在开放寻址哈希表中直接删除元素</strong>。这是因为删除元素会在数组内产生一个空桶 <code>None</code> ,而当查询元素时,线性探测到该空桶就会返回,因此在该空桶之下的元素都无法再被访问到,程序可能误判这些元素不存在。</p>
<p><a class="glightbox" href="../hash_collision.assets/hash_table_open_addressing_deletion.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="在开放寻址中删除元素导致的查询问题" class="animation-figure" src="../hash_collision.assets/hash_table_open_addressing_deletion.png" /></a></p>
<p align="center"> 图 6-7 &nbsp; 在开放寻址中删除元素导致的查询问题 </p>
<p>为了解决该问题,我们可以采用「懒删除 lazy deletion」机制:它不直接从哈希表中移除元素,<strong>而是利用一个常量 <code>TOMBSTONE</code> 来标记这个桶</strong>。在该机制下,<span class="arithmatex">\(\text{None}\)</span><code>TOMBSTONE</code> 都代表空桶,都可以放置键值对。但不同的是,线性探测到 <code>TOMBSTONE</code> 时应该继续遍历,因为其之下可能还存在键值对。</p>
<p>为了解决该问题,我们可以采用「懒删除 lazy deletion」机制:它不直接从哈希表中移除元素,<strong>而是利用一个常量 <code>TOMBSTONE</code> 来标记这个桶</strong>。在该机制下,<code>None</code><code>TOMBSTONE</code> 都代表空桶,都可以放置键值对。但不同的是,线性探测到 <code>TOMBSTONE</code> 时应该继续遍历,因为其之下可能还存在键值对。</p>
<p>然而,<strong>懒删除可能会加速哈希表的性能退化</strong>。这是因为每次删除操作都会产生一个删除标记,随着 <code>TOMBSTONE</code> 的增加,搜索时间也会增加,因为线性探测可能需要跳过多个 <code>TOMBSTONE</code> 才能找到目标元素。</p>
<p>为此,考虑在线性探测中记录遇到的首个 <code>TOMBSTONE</code> 的索引,并将搜索到的目标元素与该 <code>TOMBSTONE</code> 交换位置。这样做的好处是当每次查询或添加元素时,元素会被移动至距离理想位置(探测起始点)更近的桶,从而优化查询效率。</p>
<p>以下代码实现了一个包含懒删除的开放寻址(线性探测)哈希表。为了更加充分地使用哈希表的空间,我们将哈希表看作一个“环形数组”,当越过数组尾部时,回到头部继续遍历。</p>
@@ -4938,9 +4938,9 @@
<a id="__codelineno-12-24" name="__codelineno-12-24" href="#__codelineno-12-24"></a> <span class="n">first_tombstone</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span>
<a id="__codelineno-12-25" name="__codelineno-12-25" href="#__codelineno-12-25"></a> <span class="c1"># 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-12-26" name="__codelineno-12-26" href="#__codelineno-12-26"></a> <span class="k">while</span> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-12-27" name="__codelineno-12-27" href="#__codelineno-12-27"></a> <span class="c1"># 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-12-27" name="__codelineno-12-27" href="#__codelineno-12-27"></a> <span class="c1"># 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-12-28" name="__codelineno-12-28" href="#__codelineno-12-28"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">.</span><span class="n">key</span> <span class="o">==</span> <span class="n">key</span><span class="p">:</span>
<a id="__codelineno-12-29" name="__codelineno-12-29" href="#__codelineno-12-29"></a> <span class="c1"># 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-12-29" name="__codelineno-12-29" href="#__codelineno-12-29"></a> <span class="c1"># 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-12-30" name="__codelineno-12-30" href="#__codelineno-12-30"></a> <span class="k">if</span> <span class="n">first_tombstone</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a id="__codelineno-12-31" name="__codelineno-12-31" href="#__codelineno-12-31"></a> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">first_tombstone</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-12-32" name="__codelineno-12-32" href="#__codelineno-12-32"></a> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">TOMBSTONE</span>
@@ -4949,7 +4949,7 @@
<a id="__codelineno-12-35" name="__codelineno-12-35" href="#__codelineno-12-35"></a> <span class="c1"># 记录遇到的首个删除标记</span>
<a id="__codelineno-12-36" name="__codelineno-12-36" href="#__codelineno-12-36"></a> <span class="k">if</span> <span class="n">first_tombstone</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="ow">is</span> <span class="bp">self</span><span class="o">.</span><span class="n">TOMBSTONE</span><span class="p">:</span>
<a id="__codelineno-12-37" name="__codelineno-12-37" href="#__codelineno-12-37"></a> <span class="n">first_tombstone</span> <span class="o">=</span> <span class="n">index</span>
<a id="__codelineno-12-38" name="__codelineno-12-38" href="#__codelineno-12-38"></a> <span class="c1"># 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-12-38" name="__codelineno-12-38" href="#__codelineno-12-38"></a> <span class="c1"># 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-12-39" name="__codelineno-12-39" href="#__codelineno-12-39"></a> <span class="n">index</span> <span class="o">=</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span>
<a id="__codelineno-12-40" name="__codelineno-12-40" href="#__codelineno-12-40"></a> <span class="c1"># 若 key 不存在,则返回添加点的索引</span>
<a id="__codelineno-12-41" name="__codelineno-12-41" href="#__codelineno-12-41"></a> <span class="k">return</span> <span class="n">index</span> <span class="k">if</span> <span class="n">first_tombstone</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="k">else</span> <span class="n">first_tombstone</span>
@@ -5054,9 +5054,9 @@
<a id="__codelineno-13-39" name="__codelineno-13-39" href="#__codelineno-13-39"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<a id="__codelineno-13-40" name="__codelineno-13-40" href="#__codelineno-13-40"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-13-41" name="__codelineno-13-41" href="#__codelineno-13-41"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">nullptr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-42" name="__codelineno-13-42" href="#__codelineno-13-42"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-13-42" name="__codelineno-13-42" href="#__codelineno-13-42"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-13-43" name="__codelineno-13-43" href="#__codelineno-13-43"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-44" name="__codelineno-13-44" href="#__codelineno-13-44"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-13-44" name="__codelineno-13-44" href="#__codelineno-13-44"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-13-45" name="__codelineno-13-45" href="#__codelineno-13-45"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">-1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-46" name="__codelineno-13-46" href="#__codelineno-13-46"></a><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-13-47" name="__codelineno-13-47" href="#__codelineno-13-47"></a><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">;</span>
@@ -5068,7 +5068,7 @@
<a id="__codelineno-13-53" name="__codelineno-13-53" href="#__codelineno-13-53"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">-1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-54" name="__codelineno-13-54" href="#__codelineno-13-54"></a><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">;</span>
<a id="__codelineno-13-55" name="__codelineno-13-55" href="#__codelineno-13-55"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-56" name="__codelineno-13-56" href="#__codelineno-13-56"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-13-56" name="__codelineno-13-56" href="#__codelineno-13-56"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-13-57" name="__codelineno-13-57" href="#__codelineno-13-57"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capacity</span><span class="p">;</span>
<a id="__codelineno-13-58" name="__codelineno-13-58" href="#__codelineno-13-58"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-59" name="__codelineno-13-59" href="#__codelineno-13-59"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5181,9 +5181,9 @@
<a id="__codelineno-14-29" name="__codelineno-14-29" href="#__codelineno-14-29"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-14-30" name="__codelineno-14-30" href="#__codelineno-14-30"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-14-31" name="__codelineno-14-31" href="#__codelineno-14-31"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-32" name="__codelineno-14-32" href="#__codelineno-14-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-14-32" name="__codelineno-14-32" href="#__codelineno-14-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-14-33" name="__codelineno-14-33" href="#__codelineno-14-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="p">.</span><span class="na">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-34" name="__codelineno-14-34" href="#__codelineno-14-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-14-34" name="__codelineno-14-34" href="#__codelineno-14-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-14-35" name="__codelineno-14-35" href="#__codelineno-14-35"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-36" name="__codelineno-14-36" href="#__codelineno-14-36"></a><span class="w"> </span><span class="n">buckets</span><span class="o">[</span><span class="n">firstTombstone</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-14-37" name="__codelineno-14-37" href="#__codelineno-14-37"></a><span class="w"> </span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">;</span>
@@ -5195,7 +5195,7 @@
<a id="__codelineno-14-43" name="__codelineno-14-43" href="#__codelineno-14-43"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">buckets</span><span class="o">[</span><span class="n">index</span><span class="o">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-44" name="__codelineno-14-44" href="#__codelineno-14-44"></a><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">;</span>
<a id="__codelineno-14-45" name="__codelineno-14-45" href="#__codelineno-14-45"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-46" name="__codelineno-14-46" href="#__codelineno-14-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-14-46" name="__codelineno-14-46" href="#__codelineno-14-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-14-47" name="__codelineno-14-47" href="#__codelineno-14-47"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capacity</span><span class="p">;</span>
<a id="__codelineno-14-48" name="__codelineno-14-48" href="#__codelineno-14-48"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-49" name="__codelineno-14-49" href="#__codelineno-14-49"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5306,9 +5306,9 @@
<a id="__codelineno-15-29" name="__codelineno-15-29" href="#__codelineno-15-29"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-15-30" name="__codelineno-15-30" href="#__codelineno-15-30"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-15-31" name="__codelineno-15-31" href="#__codelineno-15-31"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="k">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-32" name="__codelineno-15-32" href="#__codelineno-15-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-15-32" name="__codelineno-15-32" href="#__codelineno-15-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-15-33" name="__codelineno-15-33" href="#__codelineno-15-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">].</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-34" name="__codelineno-15-34" href="#__codelineno-15-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-15-34" name="__codelineno-15-34" href="#__codelineno-15-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-15-35" name="__codelineno-15-35" href="#__codelineno-15-35"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-36" name="__codelineno-15-36" href="#__codelineno-15-36"></a><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-15-37" name="__codelineno-15-37" href="#__codelineno-15-37"></a><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">;</span>
@@ -5320,7 +5320,7 @@
<a id="__codelineno-15-43" name="__codelineno-15-43" href="#__codelineno-15-43"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">TOMBSTONE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-44" name="__codelineno-15-44" href="#__codelineno-15-44"></a><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">;</span>
<a id="__codelineno-15-45" name="__codelineno-15-45" href="#__codelineno-15-45"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-46" name="__codelineno-15-46" href="#__codelineno-15-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-15-46" name="__codelineno-15-46" href="#__codelineno-15-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-15-47" name="__codelineno-15-47" href="#__codelineno-15-47"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capacity</span><span class="p">;</span>
<a id="__codelineno-15-48" name="__codelineno-15-48" href="#__codelineno-15-48"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-49" name="__codelineno-15-49" href="#__codelineno-15-49"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5441,7 +5441,7 @@
<a id="__codelineno-16-39" name="__codelineno-16-39" href="#__codelineno-16-39"></a><span class="w"> </span><span class="nx">idx</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">hashFunc</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span>
<a id="__codelineno-16-40" name="__codelineno-16-40" href="#__codelineno-16-40"></a><span class="w"> </span><span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-16-41" name="__codelineno-16-41" href="#__codelineno-16-41"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-42" name="__codelineno-16-42" href="#__codelineno-16-42"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-42" name="__codelineno-16-42" href="#__codelineno-16-42"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-43" name="__codelineno-16-43" href="#__codelineno-16-43"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">(</span><span class="nx">idx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span>
<a id="__codelineno-16-44" name="__codelineno-16-44" href="#__codelineno-16-44"></a><span class="w"> </span><span class="c1">// 若遇到空桶,说明无此 key ,则返回 null</span>
<a id="__codelineno-16-45" name="__codelineno-16-45" href="#__codelineno-16-45"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">(</span><span class="nx">pair</span><span class="p">{})</span><span class="w"> </span><span class="p">{</span>
@@ -5452,7 +5452,7 @@
<a id="__codelineno-16-50" name="__codelineno-16-50" href="#__codelineno-16-50"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">j</span><span class="p">].</span><span class="nx">val</span>
<a id="__codelineno-16-51" name="__codelineno-16-51" href="#__codelineno-16-51"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-52" name="__codelineno-16-52" href="#__codelineno-16-52"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-53" name="__codelineno-16-53" href="#__codelineno-16-53"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-16-53" name="__codelineno-16-53" href="#__codelineno-16-53"></a><span class="w"> </span><span class="c1">// 若未找到 key 则返回空字符串</span>
<a id="__codelineno-16-54" name="__codelineno-16-54" href="#__codelineno-16-54"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="s">&quot;&quot;</span>
<a id="__codelineno-16-55" name="__codelineno-16-55" href="#__codelineno-16-55"></a><span class="p">}</span>
<a id="__codelineno-16-56" name="__codelineno-16-56" href="#__codelineno-16-56"></a>
@@ -5465,7 +5465,7 @@
<a id="__codelineno-16-63" name="__codelineno-16-63" href="#__codelineno-16-63"></a><span class="w"> </span><span class="nx">idx</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">hashFunc</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span>
<a id="__codelineno-16-64" name="__codelineno-16-64" href="#__codelineno-16-64"></a><span class="w"> </span><span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-16-65" name="__codelineno-16-65" href="#__codelineno-16-65"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-66" name="__codelineno-16-66" href="#__codelineno-16-66"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-66" name="__codelineno-16-66" href="#__codelineno-16-66"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-67" name="__codelineno-16-67" href="#__codelineno-16-67"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">(</span><span class="nx">idx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span>
<a id="__codelineno-16-68" name="__codelineno-16-68" href="#__codelineno-16-68"></a><span class="w"> </span><span class="c1">// 若遇到空桶、或带有删除标记的桶,则将键值对放入该桶</span>
<a id="__codelineno-16-69" name="__codelineno-16-69" href="#__codelineno-16-69"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">(</span><span class="nx">pair</span><span class="p">{})</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">removed</span><span class="w"> </span><span class="p">{</span>
@@ -5490,7 +5490,7 @@
<a id="__codelineno-16-88" name="__codelineno-16-88" href="#__codelineno-16-88"></a><span class="w"> </span><span class="c1">// 遍历桶,从中删除键值对</span>
<a id="__codelineno-16-89" name="__codelineno-16-89" href="#__codelineno-16-89"></a><span class="w"> </span><span class="c1">// 线性探测,从 index 开始向后遍历</span>
<a id="__codelineno-16-90" name="__codelineno-16-90" href="#__codelineno-16-90"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span><span class="w"> </span><span class="nx">i</span><span class="o">++</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-91" name="__codelineno-16-91" href="#__codelineno-16-91"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-91" name="__codelineno-16-91" href="#__codelineno-16-91"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-16-92" name="__codelineno-16-92" href="#__codelineno-16-92"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">(</span><span class="nx">idx</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">capacity</span>
<a id="__codelineno-16-93" name="__codelineno-16-93" href="#__codelineno-16-93"></a><span class="w"> </span><span class="c1">// 若遇到空桶,说明无此 key ,则直接返回</span>
<a id="__codelineno-16-94" name="__codelineno-16-94" href="#__codelineno-16-94"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">(</span><span class="nx">pair</span><span class="p">{})</span><span class="w"> </span><span class="p">{</span>
@@ -5570,9 +5570,9 @@
<a id="__codelineno-17-33" name="__codelineno-17-33" href="#__codelineno-17-33"></a> <span class="kd">var</span> <span class="nv">firstTombstone</span> <span class="p">=</span> <span class="o">-</span><span class="mi">1</span>
<a id="__codelineno-17-34" name="__codelineno-17-34" href="#__codelineno-17-34"></a> <span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-17-35" name="__codelineno-17-35" href="#__codelineno-17-35"></a> <span class="k">while</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<a id="__codelineno-17-36" name="__codelineno-17-36" href="#__codelineno-17-36"></a> <span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-17-36" name="__codelineno-17-36" href="#__codelineno-17-36"></a> <span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-17-37" name="__codelineno-17-37" href="#__codelineno-17-37"></a> <span class="k">if</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">!</span><span class="p">.</span><span class="n">key</span> <span class="p">==</span> <span class="n">key</span> <span class="p">{</span>
<a id="__codelineno-17-38" name="__codelineno-17-38" href="#__codelineno-17-38"></a> <span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-17-38" name="__codelineno-17-38" href="#__codelineno-17-38"></a> <span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-17-39" name="__codelineno-17-39" href="#__codelineno-17-39"></a> <span class="k">if</span> <span class="n">firstTombstone</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span> <span class="p">{</span>
<a id="__codelineno-17-40" name="__codelineno-17-40" href="#__codelineno-17-40"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">firstTombstone</span><span class="p">]</span> <span class="p">=</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span>
<a id="__codelineno-17-41" name="__codelineno-17-41" href="#__codelineno-17-41"></a> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">=</span> <span class="n">TOMBSTONE</span>
@@ -5584,7 +5584,7 @@
<a id="__codelineno-17-47" name="__codelineno-17-47" href="#__codelineno-17-47"></a> <span class="k">if</span> <span class="n">firstTombstone</span> <span class="p">==</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span> <span class="p">==</span> <span class="n">TOMBSTONE</span> <span class="p">{</span>
<a id="__codelineno-17-48" name="__codelineno-17-48" href="#__codelineno-17-48"></a> <span class="n">firstTombstone</span> <span class="p">=</span> <span class="n">index</span>
<a id="__codelineno-17-49" name="__codelineno-17-49" href="#__codelineno-17-49"></a> <span class="p">}</span>
<a id="__codelineno-17-50" name="__codelineno-17-50" href="#__codelineno-17-50"></a> <span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-17-50" name="__codelineno-17-50" href="#__codelineno-17-50"></a> <span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-17-51" name="__codelineno-17-51" href="#__codelineno-17-51"></a> <span class="n">index</span> <span class="p">=</span> <span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span>
<a id="__codelineno-17-52" name="__codelineno-17-52" href="#__codelineno-17-52"></a> <span class="p">}</span>
<a id="__codelineno-17-53" name="__codelineno-17-53" href="#__codelineno-17-53"></a> <span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5699,9 +5699,9 @@
<a id="__codelineno-18-33" name="__codelineno-18-33" href="#__codelineno-18-33"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-18-34" name="__codelineno-18-34" href="#__codelineno-18-34"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-18-35" name="__codelineno-18-35" href="#__codelineno-18-35"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span><span class="w"> </span><span class="o">!==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-36" name="__codelineno-18-36" href="#__codelineno-18-36"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-18-36" name="__codelineno-18-36" href="#__codelineno-18-36"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-18-37" name="__codelineno-18-37" href="#__codelineno-18-37"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">].</span><span class="nx">key</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-38" name="__codelineno-18-38" href="#__codelineno-18-38"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-18-38" name="__codelineno-18-38" href="#__codelineno-18-38"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-18-39" name="__codelineno-18-39" href="#__codelineno-18-39"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">!==</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-40" name="__codelineno-18-40" href="#__codelineno-18-40"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-18-41" name="__codelineno-18-41" href="#__codelineno-18-41"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">TOMBSTONE</span><span class="p">;</span>
@@ -5716,7 +5716,7 @@
<a id="__codelineno-18-50" name="__codelineno-18-50" href="#__codelineno-18-50"></a><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-51" name="__codelineno-18-51" href="#__codelineno-18-51"></a><span class="w"> </span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">index</span><span class="p">;</span>
<a id="__codelineno-18-52" name="__codelineno-18-52" href="#__codelineno-18-52"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-53" name="__codelineno-18-53" href="#__codelineno-18-53"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-18-53" name="__codelineno-18-53" href="#__codelineno-18-53"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-18-54" name="__codelineno-18-54" href="#__codelineno-18-54"></a><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-18-55" name="__codelineno-18-55" href="#__codelineno-18-55"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-56" name="__codelineno-18-56" href="#__codelineno-18-56"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5840,9 +5840,9 @@
<a id="__codelineno-19-33" name="__codelineno-19-33" href="#__codelineno-19-33"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-19-34" name="__codelineno-19-34" href="#__codelineno-19-34"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-19-35" name="__codelineno-19-35" href="#__codelineno-19-35"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span><span class="w"> </span><span class="o">!==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-19-36" name="__codelineno-19-36" href="#__codelineno-19-36"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-19-37" name="__codelineno-19-37" href="#__codelineno-19-37"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span><span class="o">!</span><span class="p">.</span><span class="nx">key</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-19-38" name="__codelineno-19-38" href="#__codelineno-19-38"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-19-39" name="__codelineno-19-39" href="#__codelineno-19-39"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">!==</span><span class="w"> </span><span class="o">-</span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-40" name="__codelineno-19-40" href="#__codelineno-19-40"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
<a id="__codelineno-19-41" name="__codelineno-19-41" href="#__codelineno-19-41"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">buckets</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">TOMBSTONE</span><span class="p">;</span>
@@ -5857,7 +5857,7 @@
<a id="__codelineno-19-50" name="__codelineno-19-50" href="#__codelineno-19-50"></a><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-51" name="__codelineno-19-51" href="#__codelineno-19-51"></a><span class="w"> </span><span class="nx">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">index</span><span class="p">;</span>
<a id="__codelineno-19-52" name="__codelineno-19-52" href="#__codelineno-19-52"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-19-53" name="__codelineno-19-53" href="#__codelineno-19-53"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-19-54" name="__codelineno-19-54" href="#__codelineno-19-54"></a><span class="w"> </span><span class="nx">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-19-55" name="__codelineno-19-55" href="#__codelineno-19-55"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-56" name="__codelineno-19-56" href="#__codelineno-19-56"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -5977,9 +5977,9 @@
<a id="__codelineno-20-29" name="__codelineno-20-29" href="#__codelineno-20-29"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-20-30" name="__codelineno-20-30" href="#__codelineno-20-30"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-20-31" name="__codelineno-20-31" href="#__codelineno-20-31"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">_buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-32" name="__codelineno-20-32" href="#__codelineno-20-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-20-32" name="__codelineno-20-32" href="#__codelineno-20-32"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-20-33" name="__codelineno-20-33" href="#__codelineno-20-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">_buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">!</span><span class="p">.</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-34" name="__codelineno-20-34" href="#__codelineno-20-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-20-34" name="__codelineno-20-34" href="#__codelineno-20-34"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-20-35" name="__codelineno-20-35" href="#__codelineno-20-35"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-36" name="__codelineno-20-36" href="#__codelineno-20-36"></a><span class="w"> </span><span class="n">_buckets</span><span class="p">[</span><span class="n">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-20-37" name="__codelineno-20-37" href="#__codelineno-20-37"></a><span class="w"> </span><span class="n">_buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_TOMBSTONE</span><span class="p">;</span>
@@ -5991,7 +5991,7 @@
<a id="__codelineno-20-43" name="__codelineno-20-43" href="#__codelineno-20-43"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="m">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">_buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">_TOMBSTONE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-44" name="__codelineno-20-44" href="#__codelineno-20-44"></a><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">;</span>
<a id="__codelineno-20-45" name="__codelineno-20-45" href="#__codelineno-20-45"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-46" name="__codelineno-20-46" href="#__codelineno-20-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-20-46" name="__codelineno-20-46" href="#__codelineno-20-46"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-20-47" name="__codelineno-20-47" href="#__codelineno-20-47"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">_capacity</span><span class="p">;</span>
<a id="__codelineno-20-48" name="__codelineno-20-48" href="#__codelineno-20-48"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-49" name="__codelineno-20-49" href="#__codelineno-20-49"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -6125,7 +6125,7 @@
<a id="__codelineno-21-52" name="__codelineno-21-52" href="#__codelineno-21-52"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">first_tombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="o">-</span><span class="mi">1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">TOMBSTONE</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-21-53" name="__codelineno-21-53" href="#__codelineno-21-53"></a><span class="w"> </span><span class="n">first_tombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="p">;</span>
<a id="__codelineno-21-54" name="__codelineno-21-54" href="#__codelineno-21-54"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-55" name="__codelineno-21-55" href="#__codelineno-21-55"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-21-55" name="__codelineno-21-55" href="#__codelineno-21-55"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-21-56" name="__codelineno-21-56" href="#__codelineno-21-56"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">capacity</span><span class="p">;</span>
<a id="__codelineno-21-57" name="__codelineno-21-57" href="#__codelineno-21-57"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-58" name="__codelineno-21-58" href="#__codelineno-21-58"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -6261,9 +6261,9 @@
<a id="__codelineno-22-50" name="__codelineno-22-50" href="#__codelineno-22-50"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">-1</span><span class="p">;</span>
<a id="__codelineno-22-51" name="__codelineno-22-51" href="#__codelineno-22-51"></a><span class="w"> </span><span class="c1">// 线性探测,当遇到空桶时跳出</span>
<a id="__codelineno-22-52" name="__codelineno-22-52" href="#__codelineno-22-52"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-53" name="__codelineno-22-53" href="#__codelineno-22-53"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-22-53" name="__codelineno-22-53" href="#__codelineno-22-53"></a><span class="w"> </span><span class="c1">// 若遇到 key ,返回对应桶索引</span>
<a id="__codelineno-22-54" name="__codelineno-22-54" href="#__codelineno-22-54"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="o">-&gt;</span><span class="n">key</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-55" name="__codelineno-22-55" href="#__codelineno-22-55"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-22-55" name="__codelineno-22-55" href="#__codelineno-22-55"></a><span class="w"> </span><span class="c1">// 若之前遇到了删除标记,则将键值对移动至该索引</span>
<a id="__codelineno-22-56" name="__codelineno-22-56" href="#__codelineno-22-56"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="mi">-1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-57" name="__codelineno-22-57" href="#__codelineno-22-57"></a><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">firstTombstone</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">];</span>
<a id="__codelineno-22-58" name="__codelineno-22-58" href="#__codelineno-22-58"></a><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">TOMBSTONE</span><span class="p">;</span>
@@ -6275,7 +6275,7 @@
<a id="__codelineno-22-64" name="__codelineno-22-64" href="#__codelineno-22-64"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="mi">-1</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">buckets</span><span class="p">[</span><span class="n">index</span><span class="p">]</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">TOMBSTONE</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-65" name="__codelineno-22-65" href="#__codelineno-22-65"></a><span class="w"> </span><span class="n">firstTombstone</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">;</span>
<a id="__codelineno-22-66" name="__codelineno-22-66" href="#__codelineno-22-66"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-22-67" name="__codelineno-22-67" href="#__codelineno-22-67"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-22-67" name="__codelineno-22-67" href="#__codelineno-22-67"></a><span class="w"> </span><span class="c1">// 计算桶索引,越过尾部返回头部</span>
<a id="__codelineno-22-68" name="__codelineno-22-68" href="#__codelineno-22-68"></a><span class="w"> </span><span class="n">index</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">index</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">hashMap</span><span class="o">-&gt;</span><span class="n">capacity</span><span class="p">;</span>
<a id="__codelineno-22-69" name="__codelineno-22-69" href="#__codelineno-22-69"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-22-70" name="__codelineno-22-70" href="#__codelineno-22-70"></a><span class="w"> </span><span class="c1">// 若 key 不存在,则返回添加点的索引</span>
@@ -6392,8 +6392,8 @@
<h3 id="3">3. &nbsp; 多次哈希<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>顾名思义,多次哈希方法使用多个哈希函数 <span class="arithmatex">\(f_1(x)\)</span><span class="arithmatex">\(f_2(x)\)</span><span class="arithmatex">\(f_3(x)\)</span><span class="arithmatex">\(\dots\)</span> 进行探测。</p>
<ul>
<li><strong>插入元素</strong>:若哈希函数 <span class="arithmatex">\(f_1(x)\)</span> 出现冲突,则尝试 <span class="arithmatex">\(f_2(x)\)</span> ,以此类推,直到找到空后插入元素。</li>
<li><strong>查找元素</strong>:在相同的哈希函数顺序下进行查找,直到找到目标元素时返回;若遇到空或已尝试所有哈希函数,说明哈希表中不存在该元素,则返回 <span class="arithmatex">\(\text{None}\)</span></li>
<li><strong>插入元素</strong>:若哈希函数 <span class="arithmatex">\(f_1(x)\)</span> 出现冲突,则尝试 <span class="arithmatex">\(f_2(x)\)</span> ,以此类推,直到找到空后插入元素。</li>
<li><strong>查找元素</strong>:在相同的哈希函数顺序下进行查找,直到找到目标元素时返回;若遇到空或已尝试所有哈希函数,说明哈希表中不存在该元素,则返回 <code>None</code></li>
</ul>
<p>与线性探测相比,多次哈希方法不易产生聚集,但多个哈希函数会带来额外的计算量。</p>
<div class="admonition tip">
@@ -6403,9 +6403,9 @@
<h2 id="623">6.2.3 &nbsp; 编程语言的选择<a class="headerlink" href="#623" title="Permanent link">&para;</a></h2>
<p>各种编程语言采取了不同的哈希表实现策略,下面举几个例子。</p>
<ul>
<li>Python 采用开放寻址。字典 dict 使用伪随机数进行探测。</li>
<li>Java 采用链式地址。自 JDK 1.8 以来,当 HashMap 内数组长度达到 64 且链表长度达到 8 时,链表会转换为红黑树以提升查找性能。</li>
<li>Go 采用链式地址。Go 规定每个桶最多存储 8 个键值对,超出容量则连接一个溢出桶当溢出桶过多时,会执行一次特殊的等量扩容操作,以确保性能。</li>
<li>Python 采用开放寻址。字典 <code>dict</code> 使用伪随机数进行探测。</li>
<li>Java 采用链式地址。自 JDK 1.8 以来,当 <code>HashMap</code> 内数组长度达到 64 且链表长度达到 8 时,链表会转换为红黑树以提升查找性能。</li>
<li>Go 采用链式地址。Go 规定每个桶最多存储 8 个键值对,超出容量则连接一个溢出桶当溢出桶过多时,会执行一次特殊的等量扩容操作,以确保性能。</li>
</ul>
<!-- Source file information -->
+12 -12
View File
@@ -1788,7 +1788,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3533,7 +3533,7 @@
<!-- Page content -->
<h1 id="61">6.1 &nbsp; 哈希表<a class="headerlink" href="#61" title="Permanent link">&para;</a></h1>
<p>「哈希表 hash table」,又称「散列表」,通过建立键 <code>key</code> 与值 <code>value</code> 之间的映射,实现高效的元素查询。具体而言,我们向哈希表输入一个键 <code>key</code> ,则可以在 <span class="arithmatex">\(O(1)\)</span> 时间内获取对应的值 <code>value</code></p>
<p>「哈希表 hash table」,又称「散列表」,通过建立键 <code>key</code> 与值 <code>value</code> 之间的映射,实现高效的元素查询。具体而言,我们向哈希表输入一个键 <code>key</code> ,则可以在 <span class="arithmatex">\(O(1)\)</span> 时间内获取对应的值 <code>value</code></p>
<p>如图 6-1 所示,给定 <span class="arithmatex">\(n\)</span> 个学生,每个学生都有“姓名”和“学号”两项数据。假如我们希望实现“输入一个学号,返回对应的姓名”的查询功能,则可以采用图 6-1 所示的哈希表来实现。</p>
<p><a class="glightbox" href="../hash_map.assets/hash_table_lookup.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="哈希表的抽象表示" class="animation-figure" src="../hash_map.assets/hash_table_lookup.png" /></a></p>
<p align="center"> 图 6-1 &nbsp; 哈希表的抽象表示 </p>
@@ -3596,7 +3596,7 @@
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a><span class="n">hmap</span><span class="p">[</span><span class="mi">10583</span><span class="p">]</span> <span class="o">=</span> <span class="s2">&quot;小鸭&quot;</span>
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>
<a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a><span class="c1"># 查询操作</span>
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a><span class="c1"># 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a><span class="c1"># 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a><span class="n">name</span><span class="p">:</span> <span class="nb">str</span> <span class="o">=</span> <span class="n">hmap</span><span class="p">[</span><span class="mi">15937</span><span class="p">]</span>
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a>
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a><span class="c1"># 删除操作</span>
@@ -3617,7 +3617,7 @@
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a><span class="n">map</span><span class="p">[</span><span class="mi">10583</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">&quot;小鸭&quot;</span><span class="p">;</span>
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a>
<a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a><span class="n">string</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">[</span><span class="mi">15937</span><span class="p">];</span>
<a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a>
<a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a><span class="cm">/* 删除操作 */</span>
@@ -3638,7 +3638,7 @@
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a><span class="n">map</span><span class="p">.</span><span class="na">put</span><span class="p">(</span><span class="mi">10583</span><span class="p">,</span><span class="w"> </span><span class="s">&quot;小鸭&quot;</span><span class="p">);</span>
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a>
<a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a><span class="n">String</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">.</span><span class="na">get</span><span class="p">(</span><span class="mi">15937</span><span class="p">);</span>
<a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a>
<a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a><span class="cm">/* 删除操作 */</span>
@@ -3659,7 +3659,7 @@
<a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a><span class="p">};</span>
<a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a>
<a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a><span class="kt">string</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">[</span><span class="m">15937</span><span class="p">];</span>
<a id="__codelineno-3-15" name="__codelineno-3-15" href="#__codelineno-3-15"></a>
<a id="__codelineno-3-16" name="__codelineno-3-16" href="#__codelineno-3-16"></a><span class="cm">/* 删除操作 */</span>
@@ -3680,7 +3680,7 @@
<a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="nx">hmap</span><span class="p">[</span><span class="mi">10583</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="s">&quot;小鸭&quot;</span>
<a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a>
<a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a><span class="nx">name</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">hmap</span><span class="p">[</span><span class="mi">15937</span><span class="p">]</span>
<a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a>
<a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a><span class="cm">/* 删除操作 */</span>
@@ -3701,7 +3701,7 @@
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a><span class="bp">map</span><span class="p">[</span><span class="mi">10583</span><span class="p">]</span> <span class="p">=</span> <span class="s">&quot;小鸭&quot;</span>
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a>
<a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a><span class="kd">let</span> <span class="nv">name</span> <span class="p">=</span> <span class="bp">map</span><span class="p">[</span><span class="mi">15937</span><span class="p">]</span><span class="o">!</span>
<a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a>
<a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a><span class="cm">/* 删除操作 */</span>
@@ -3721,7 +3721,7 @@
<a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a><span class="nx">map</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="mf">10583</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;小鸭&#39;</span><span class="p">);</span>
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a>
<a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a><span class="kd">let</span><span class="w"> </span><span class="nx">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">map</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="mf">15937</span><span class="p">);</span>
<a id="__codelineno-6-14" name="__codelineno-6-14" href="#__codelineno-6-14"></a>
<a id="__codelineno-6-15" name="__codelineno-6-15" href="#__codelineno-6-15"></a><span class="cm">/* 删除操作 */</span>
@@ -3743,7 +3743,7 @@
<a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a><span class="nx">console</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="nx">map</span><span class="p">);</span>
<a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a>
<a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a><span class="kd">let</span><span class="w"> </span><span class="nx">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">map</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="mf">15937</span><span class="p">);</span>
<a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a><span class="nx">console</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="s1">&#39;\n输入学号 15937 ,查询到姓名 &#39;</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">name</span><span class="p">);</span>
<a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a>
@@ -3767,7 +3767,7 @@
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="n">map</span><span class="p">[</span><span class="m">10583</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">&quot;小鸭&quot;</span><span class="p">;</span>
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a>
<a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="cm">/* 查询操作 */</span>
<a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="c1">// 向哈希表输入键 key ,得到值 value</span>
<a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a><span class="kt">String</span><span class="w"> </span><span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">map</span><span class="p">[</span><span class="m">15937</span><span class="p">];</span>
<a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a>
<a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a><span class="cm">/* 删除操作 */</span>
@@ -5123,7 +5123,7 @@
<p><a class="glightbox" href="../hash_map.assets/hash_table_reshash.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="哈希表扩容" class="animation-figure" src="../hash_map.assets/hash_table_reshash.png" /></a></p>
<p align="center"> 图 6-4 &nbsp; 哈希表扩容 </p>
<p>类似于数组扩容,哈希表扩容需将所有键值对从原哈希表迁移至新哈希表,非常耗时;并且由于哈希表容量 <code>capacity</code> 改变,我们需要通过哈希函数来重新计算所有键值对的存储位置,这进一步提高了扩容过程的计算开销。为此,编程语言通常会预留足够大的哈希表容量,防止频繁扩容。</p>
<p>类似于数组扩容,哈希表扩容需将所有键值对从原哈希表迁移至新哈希表,非常耗时;并且由于哈希表容量 <code>capacity</code> 改变,我们需要通过哈希函数来重新计算所有键值对的存储位置,这进一步增加了扩容过程的计算开销。为此,编程语言通常会预留足够大的哈希表容量,防止频繁扩容。</p>
<p>「负载因子 load factor」是哈希表的一个重要概念,其定义为哈希表的元素数量除以桶数量,用于衡量哈希冲突的严重程度,<strong>也常作为哈希表扩容的触发条件</strong>。例如在 Java 中,当负载因子超过 <span class="arithmatex">\(0.75\)</span> 时,系统会将哈希表扩容至原先的 <span class="arithmatex">\(2\)</span> 倍。</p>
<!-- Source file information -->
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+2 -2
View File
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3556,7 +3556,7 @@
</div>
<div class="admonition question">
<p class="admonition-title">为什么哈希表扩容能够缓解哈希冲突?</p>
<p>哈希函数的最后一步往往是对数组长度 <span class="arithmatex">\(n\)</span>,让输出值落在数组索引范围内;在扩容后,数组长度 <span class="arithmatex">\(n\)</span> 发生变化,而 <code>key</code> 对应的索引也可能发生变化。原先落在同一个桶的多个 <code>key</code> ,在扩容后可能会被分配到多个桶中,从而实现哈希冲突的缓解。</p>
<p>哈希函数的最后一步往往是对数组长度 <span class="arithmatex">\(n\)</span>模(取余),让输出值落在数组索引范围内;在扩容后,数组长度 <span class="arithmatex">\(n\)</span> 发生变化,而 <code>key</code> 对应的索引也可能发生变化。原先落在同一个桶的多个 <code>key</code> ,在扩容后可能会被分配到多个桶中,从而实现哈希冲突的缓解。</p>
</div>
<!-- Source file information -->
+7 -7
View File
@@ -1788,7 +1788,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3717,7 +3717,7 @@
<div class="arithmatex">\[
T(h) = 2^0h + 2^1(h-1) + 2^2(h-2) + \dots + 2^{(h-1)}\times1
\]</div>
<p>化简上式需要借助中学的数列知识,<span class="arithmatex">\(T(h)\)</span> 乘以 <span class="arithmatex">\(2\)</span> ,得到:</p>
<p>化简上式需要借助中学的数列知识,<span class="arithmatex">\(T(h)\)</span> 乘以 <span class="arithmatex">\(2\)</span> ,得到:</p>
<div class="arithmatex">\[
\begin{aligned}
T(h) &amp; = 2^0h + 2^1(h-1) + 2^2(h-2) + \dots + 2^{h-1}\times1 \newline
@@ -3736,7 +3736,7 @@ T(h) &amp; = 2 \frac{1 - 2^h}{1 - 2} - h \newline
&amp; = O(2^h)
\end{aligned}
\]</div>
<p>进一步,高度为 <span class="arithmatex">\(h\)</span> 的完美二叉树的节点数量为 <span class="arithmatex">\(n = 2^{h+1} - 1\)</span> ,易得复杂度为 <span class="arithmatex">\(O(2^h) = O(n)\)</span> 。以上推算表明,<strong>输入列表并建堆的时间复杂度为 <span class="arithmatex">\(O(n)\)</span> ,非常高效</strong></p>
<p>进一步,高度为 <span class="arithmatex">\(h\)</span> 的完美二叉树的节点数量为 <span class="arithmatex">\(n = 2^{h+1} - 1\)</span> ,易得复杂度为 <span class="arithmatex">\(O(2^h) = O(n)\)</span> 。以上推算表明,<strong>输入列表并建堆的时间复杂度为 <span class="arithmatex">\(O(n)\)</span> ,非常高效</strong></p>
<!-- Source file information -->
@@ -3783,7 +3783,7 @@ aria-label="页脚"
<a
href="../top_k/"
class="md-footer__link md-footer__link--next"
aria-label="下一页: 8.3 &amp;nbsp; Top-K 问题"
aria-label="下一页: 8.3 &amp;nbsp; Top-k 问题"
rel="next"
>
<div class="md-footer__title">
@@ -3791,7 +3791,7 @@ aria-label="页脚"
下一页
</span>
<div class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</div>
</div>
<div class="md-footer__button md-icon">
@@ -3901,13 +3901,13 @@ aria-label="页脚"
<a href="../top_k/" class="md-footer__link md-footer__link--next" aria-label="下一页: 8.3 &amp;nbsp; Top-K 问题">
<a href="../top_k/" class="md-footer__link md-footer__link--next" aria-label="下一页: 8.3 &amp;nbsp; Top-k 问题">
<div class="md-footer__title">
<span class="md-footer__direction">
下一页
</span>
<div class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</div>
</div>
<div class="md-footer__button md-icon">
+54 -54
View File
@@ -1723,7 +1723,7 @@
<li class="md-nav__item">
<a href="#811" class="md-nav__link">
<span class="md-ellipsis">
8.1.1 &nbsp; 堆常用操作
8.1.1 &nbsp;常用操作
</span>
</a>
@@ -1783,7 +1783,7 @@
<li class="md-nav__item">
<a href="#813" class="md-nav__link">
<span class="md-ellipsis">
8.1.3 &nbsp; 堆常见应用
8.1.3 &nbsp;常见应用
</span>
</a>
@@ -1830,7 +1830,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3514,7 +3514,7 @@
<li class="md-nav__item">
<a href="#811" class="md-nav__link">
<span class="md-ellipsis">
8.1.1 &nbsp; 堆常用操作
8.1.1 &nbsp;常用操作
</span>
</a>
@@ -3574,7 +3574,7 @@
<li class="md-nav__item">
<a href="#813" class="md-nav__link">
<span class="md-ellipsis">
8.1.3 &nbsp; 堆常见应用
8.1.3 &nbsp;常见应用
</span>
</a>
@@ -3619,8 +3619,8 @@
<h1 id="81">8.1 &nbsp;<a class="headerlink" href="#81" title="Permanent link">&para;</a></h1>
<p>「堆 heap」是一种满足特定条件的完全二叉树,主要可分为两种类型,如图 8-1 所示。</p>
<ul>
<li>「大顶堆 max heap」:任意节点的值 <span class="arithmatex">\(\geq\)</span> 其子节点的值。</li>
<li>「小顶堆 min heap」:任意节点的值 <span class="arithmatex">\(\leq\)</span> 其子节点的值。</li>
<li>「大顶堆 max heap」:任意节点的值 <span class="arithmatex">\(\geq\)</span> 其子节点的值。</li>
</ul>
<p><a class="glightbox" href="../heap.assets/min_heap_and_max_heap.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="小顶堆与大顶堆" class="animation-figure" src="../heap.assets/min_heap_and_max_heap.png" /></a></p>
<p align="center"> 图 8-1 &nbsp; 小顶堆与大顶堆 </p>
@@ -3629,10 +3629,10 @@
<ul>
<li>最底层节点靠左填充,其他层的节点都被填满。</li>
<li>我们将二叉树的根节点称为“堆顶”,将底层最靠右的节点称为“堆底”。</li>
<li>对于大顶堆(小顶堆),堆顶元素(根节点)的值分别是最大(最小)的。</li>
<li>对于大顶堆(小顶堆),堆顶元素(根节点)的值是最大(最小)的。</li>
</ul>
<h2 id="811">8.1.1 &nbsp; 堆常用操作<a class="headerlink" href="#811" title="Permanent link">&para;</a></h2>
<p>需要指出的是,许多编程语言提供的是「优先队列 priority queue」,这是一种抽象数据结构,定义为具有优先级排序的队列。</p>
<h2 id="811">8.1.1 &nbsp;常用操作<a class="headerlink" href="#811" title="Permanent link">&para;</a></h2>
<p>需要指出的是,许多编程语言提供的是「优先队列 priority queue」,这是一种抽象数据结构,定义为具有优先级排序的队列。</p>
<p>实际上,<strong>堆通常用于实现优先队列,大顶堆相当于元素按从大到小的顺序出队的优先队列</strong>。从使用角度来看,我们可以将“优先队列”和“堆”看作等价的数据结构。因此,本书对两者不做特别区分,统一称作“堆”。</p>
<p>堆的常用操作见表 8-1 ,方法名需要根据编程语言来确定。</p>
<p align="center"> 表 8-1 &nbsp; 堆的操作效率 </p>
@@ -3648,27 +3648,27 @@
</thead>
<tbody>
<tr>
<td>push()</td>
<td><code>push()</code></td>
<td>元素入堆</td>
<td><span class="arithmatex">\(O(\log n)\)</span></td>
</tr>
<tr>
<td>pop()</td>
<td><code>pop()</code></td>
<td>堆顶元素出堆</td>
<td><span class="arithmatex">\(O(\log n)\)</span></td>
</tr>
<tr>
<td>peek()</td>
<td>访问堆顶元素(大 / 小顶堆分别为最大 / 小值)</td>
<td><code>peek()</code></td>
<td>访问堆顶元素(对于大 / 小顶堆分别为最大 / 小值)</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>size()</td>
<td><code>size()</code></td>
<td>获取堆的元素数量</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>isEmpty()</td>
<td><code>isEmpty()</code></td>
<td>判断堆是否为空</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
@@ -3970,7 +3970,7 @@
<h3 id="1">1. &nbsp; 堆的存储与表示<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
<p>“二叉树”章节讲过,完全二叉树非常适合用数组来表示。由于堆正是一种完全二叉树,<strong>因此我们将采用数组来存储堆</strong></p>
<p>当使用数组表示二叉树时,元素代表节点值,索引代表节点在二叉树中的位置。<strong>节点指针通过索引映射公式来实现</strong></p>
<p>如图 8-2 所示,给定索引 <span class="arithmatex">\(i\)</span> ,其左子节点索引为 <span class="arithmatex">\(2i + 1\)</span> ,右子节点索引为 <span class="arithmatex">\(2i + 2\)</span> ,父节点索引为 <span class="arithmatex">\((i - 1) / 2\)</span>(向下整除)。当索引越界时,表示空节点或节点不存在。</p>
<p>如图 8-2 所示,给定索引 <span class="arithmatex">\(i\)</span> ,其左子节点索引为 <span class="arithmatex">\(2i + 1\)</span> ,右子节点索引为 <span class="arithmatex">\(2i + 2\)</span> ,父节点索引为 <span class="arithmatex">\((i - 1) / 2\)</span>(向下整除)。当索引越界时,表示空节点或节点不存在。</p>
<p><a class="glightbox" href="../heap.assets/representation_of_heap.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="堆的表示与存储" class="animation-figure" src="../heap.assets/representation_of_heap.png" /></a></p>
<p align="center"> 图 8-2 &nbsp; 堆的表示与存储 </p>
@@ -3979,81 +3979,81 @@
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.py</span><pre><span></span><code><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="k">def</span> <span class="nf">left</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取左子节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取左子节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> <span class="k">return</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
<a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a>
<a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a><span class="k">def</span> <span class="nf">right</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取右子节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取右子节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a> <span class="k">return</span> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">2</span>
<a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a>
<a id="__codelineno-12-9" name="__codelineno-12-9" href="#__codelineno-12-9"></a><span class="k">def</span> <span class="nf">parent</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">i</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取父节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;获取父节点索引&quot;&quot;&quot;</span>
<a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a> <span class="k">return</span> <span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">//</span> <span class="mi">2</span> <span class="c1"># 向下整除</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.cpp</span><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.cpp</span><pre><span></span><code><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">left</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="p">}</span>
<a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a>
<a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="kt">int</span><span class="w"> </span><span class="nf">right</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span>
<a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a><span class="p">}</span>
<a id="__codelineno-13-10" name="__codelineno-13-10" href="#__codelineno-13-10"></a>
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-13-11" name="__codelineno-13-11" href="#__codelineno-13-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-13-12" name="__codelineno-13-12" href="#__codelineno-13-12"></a><span class="kt">int</span><span class="w"> </span><span class="nf">parent</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.java</span><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.java</span><pre><span></span><code><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">left</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="p">}</span>
<a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a>
<a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="kt">int</span><span class="w"> </span><span class="nf">right</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span>
<a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></a><span class="p">}</span>
<a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a>
<a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-14-12" name="__codelineno-14-12" href="#__codelineno-14-12"></a><span class="kt">int</span><span class="w"> </span><span class="nf">parent</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-13" name="__codelineno-14-13" href="#__codelineno-14-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-14-14" name="__codelineno-14-14" href="#__codelineno-14-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.cs</span><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.cs</span><pre><span></span><code><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">Left</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="p">}</span>
<a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a>
<a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="kt">int</span><span class="w"> </span><span class="nf">Right</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">2</span><span class="p">;</span>
<a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a><span class="p">}</span>
<a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a>
<a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="kt">int</span><span class="w"> </span><span class="nf">Parent</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="m">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.go</span><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.go</span><pre><span></span><code><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">h</span><span class="w"> </span><span class="o">*</span><span class="nx">maxHeap</span><span class="p">)</span><span class="w"> </span><span class="nx">left</span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="o">*</span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span>
<a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="p">}</span>
<a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a>
<a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">h</span><span class="w"> </span><span class="o">*</span><span class="nx">maxHeap</span><span class="p">)</span><span class="w"> </span><span class="nx">right</span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="o">*</span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span>
<a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a><span class="p">}</span>
<a id="__codelineno-16-10" name="__codelineno-16-10" href="#__codelineno-16-10"></a>
<a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">h</span><span class="w"> </span><span class="o">*</span><span class="nx">maxHeap</span><span class="p">)</span><span class="w"> </span><span class="nx">parent</span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span>
@@ -4061,119 +4061,119 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.swift</span><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.swift</span><pre><span></span><code><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="kd">func</span> <span class="nf">left</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span>
<a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="p">}</span>
<a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a>
<a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a><span class="kd">func</span> <span class="nf">right</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a> <span class="mi">2</span> <span class="o">*</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">2</span>
<a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a><span class="p">}</span>
<a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a>
<a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a><span class="kd">func</span> <span class="nf">parent</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a> <span class="p">(</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">// 向下整除</span>
<a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.js</span><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.js</span><pre><span></span><code><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="err">#</span><span class="nx">left</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="p">}</span>
<a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a>
<a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a><span class="err">#</span><span class="nx">right</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span>
<a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a><span class="p">}</span>
<a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a>
<a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-18-11" name="__codelineno-18-11" href="#__codelineno-18-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-18-12" name="__codelineno-18-12" href="#__codelineno-18-12"></a><span class="err">#</span><span class="nx">parent</span><span class="p">(</span><span class="nx">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">((</span><span class="nx">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">2</span><span class="p">);</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.ts</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.ts</span><pre><span></span><code><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="nx">left</span><span class="p">(</span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
<a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="p">}</span>
<a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a>
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a><span class="nx">right</span><span class="p">(</span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mf">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">2</span><span class="p">;</span>
<a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a><span class="p">}</span>
<a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a>
<a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a><span class="nx">parent</span><span class="p">(</span><span class="nx">i</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">((</span><span class="nx">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">2</span><span class="p">);</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.dart</span><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.dart</span><pre><span></span><code><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="kt">int</span><span class="w"> </span><span class="n">_left</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">;</span>
<a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="p">}</span>
<a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a>
<a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-20-6" name="__codelineno-20-6" href="#__codelineno-20-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-20-7" name="__codelineno-20-7" href="#__codelineno-20-7"></a><span class="kt">int</span><span class="w"> </span><span class="n">_right</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-8" name="__codelineno-20-8" href="#__codelineno-20-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="m">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">2</span><span class="p">;</span>
<a id="__codelineno-20-9" name="__codelineno-20-9" href="#__codelineno-20-9"></a><span class="p">}</span>
<a id="__codelineno-20-10" name="__codelineno-20-10" href="#__codelineno-20-10"></a>
<a id="__codelineno-20-11" name="__codelineno-20-11" href="#__codelineno-20-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-20-11" name="__codelineno-20-11" href="#__codelineno-20-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-20-12" name="__codelineno-20-12" href="#__codelineno-20-12"></a><span class="kt">int</span><span class="w"> </span><span class="n">_parent</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-13" name="__codelineno-20-13" href="#__codelineno-20-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">~/</span><span class="w"> </span><span class="m">2</span><span class="p">;</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-20-14" name="__codelineno-20-14" href="#__codelineno-20-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.rs</span><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.rs</span><pre><span></span><code><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="k">fn</span> <span class="nf">left</span><span class="p">(</span><span class="n">i</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span>
<a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span>
<a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="p">}</span>
<a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a>
<a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a><span class="k">fn</span> <span class="nf">right</span><span class="p">(</span><span class="n">i</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span>
<a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span>
<a id="__codelineno-21-9" name="__codelineno-21-9" href="#__codelineno-21-9"></a><span class="p">}</span>
<a id="__codelineno-21-10" name="__codelineno-21-10" href="#__codelineno-21-10"></a>
<a id="__codelineno-21-11" name="__codelineno-21-11" href="#__codelineno-21-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-21-11" name="__codelineno-21-11" href="#__codelineno-21-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-21-12" name="__codelineno-21-12" href="#__codelineno-21-12"></a><span class="k">fn</span> <span class="nf">parent</span><span class="p">(</span><span class="n">i</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span>
<a id="__codelineno-21-13" name="__codelineno-21-13" href="#__codelineno-21-13"></a><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="c1">// 向下整除</span>
<a id="__codelineno-21-14" name="__codelineno-21-14" href="#__codelineno-21-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.c</span><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<div class="highlight"><span class="filename">my_heap.c</span><pre><span></span><code><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="cm">/* 获取左子节点索引 */</span>
<a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">left</span><span class="p">(</span><span class="n">MaxHeap</span><span class="w"> </span><span class="o">*</span><span class="n">maxHeap</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="p">}</span>
<a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a>
<a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="cm">/* 获取右子节点索引 */</span>
<a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a><span class="kt">int</span><span class="w"> </span><span class="nf">right</span><span class="p">(</span><span class="n">MaxHeap</span><span class="w"> </span><span class="o">*</span><span class="n">maxHeap</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span>
<a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a><span class="p">}</span>
<a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a>
<a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a><span class="cm">/* 获取父节点索引 */</span>
<a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a><span class="kt">int</span><span class="w"> </span><span class="nf">parent</span><span class="p">(</span><span class="n">MaxHeap</span><span class="w"> </span><span class="o">*</span><span class="n">maxHeap</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span>
<a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">my_heap.zig</span><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="c1">// 获取左子节点索引</span>
<div class="highlight"><span class="filename">my_heap.zig</span><pre><span></span><code><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="c1">// 获取左子节点索引</span>
<a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="k">fn</span><span class="w"> </span><span class="n">left</span><span class="p">(</span><span class="n">i</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="p">}</span>
<a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a>
<a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="c1">// 获取右子节点索引</span>
<a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a><span class="c1">// 获取右子节点索引</span>
<a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="k">fn</span><span class="w"> </span><span class="n">right</span><span class="p">(</span><span class="n">i</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="mi">2</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">2</span><span class="p">;</span>
<a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a><span class="p">}</span>
<a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a>
<a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a><span class="c1">// 获取父节点索引</span>
<a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a><span class="c1">// 获取父节点索引</span>
<a id="__codelineno-23-12" name="__codelineno-23-12" href="#__codelineno-23-12"></a><span class="k">fn</span><span class="w"> </span><span class="n">parent</span><span class="p">(</span><span class="n">i</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-23-13" name="__codelineno-23-13" href="#__codelineno-23-13"></a><span class="w"> </span><span class="c1">// return (i - 1) / 2; // 向下整除</span>
<a id="__codelineno-23-14" name="__codelineno-23-14" href="#__codelineno-23-14"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">@divFloor</span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">);</span>
@@ -4272,7 +4272,7 @@
</div>
</div>
<h3 id="3">3. &nbsp; 元素入堆<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>给定元素 <code>val</code> ,我们首先将其添加到堆底。添加之后,由于 val 可能大于堆中其他元素,堆的成立条件可能已被破坏,<strong>因此需要修复从插入节点到根节点的路径上的各个节点</strong>,这个操作被称为「堆化 heapify」。</p>
<p>给定元素 <code>val</code> ,我们首先将其添加到堆底。添加之后,由于 <code>val</code> 可能大于堆中其他元素,堆的成立条件可能已被破坏,<strong>因此需要修复从插入节点到根节点的路径上的各个节点</strong>,这个操作被称为「堆化 heapify」。</p>
<p>考虑从入堆节点开始,<strong>从底至顶执行堆化</strong>。如图 8-3 所示,我们比较插入节点与其父节点的值,如果插入节点更大,则将它们交换。然后继续执行此操作,从底至顶修复堆中的各个节点,直至越过根节点或遇到无须交换的节点时结束。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="4:9"><input checked="checked" id="__tabbed_4_1" name="__tabbed_4" type="radio" /><input id="__tabbed_4_2" name="__tabbed_4" type="radio" /><input id="__tabbed_4_3" name="__tabbed_4" type="radio" /><input id="__tabbed_4_4" name="__tabbed_4" type="radio" /><input id="__tabbed_4_5" name="__tabbed_4" type="radio" /><input id="__tabbed_4_6" name="__tabbed_4" type="radio" /><input id="__tabbed_4_7" name="__tabbed_4" type="radio" /><input id="__tabbed_4_8" name="__tabbed_4" type="radio" /><input id="__tabbed_4_9" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">&lt;1&gt;</label><label for="__tabbed_4_2">&lt;2&gt;</label><label for="__tabbed_4_3">&lt;3&gt;</label><label for="__tabbed_4_4">&lt;4&gt;</label><label for="__tabbed_4_5">&lt;5&gt;</label><label for="__tabbed_4_6">&lt;6&gt;</label><label for="__tabbed_4_7">&lt;7&gt;</label><label for="__tabbed_4_8">&lt;8&gt;</label><label for="__tabbed_4_9">&lt;9&gt;</label></div>
<div class="tabbed-content">
@@ -5120,7 +5120,7 @@
</div>
</div>
</div>
<h2 id="813">8.1.3 &nbsp; 堆常见应用<a class="headerlink" href="#813" title="Permanent link">&para;</a></h2>
<h2 id="813">8.1.3 &nbsp;常见应用<a class="headerlink" href="#813" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>优先队列</strong>:堆通常作为实现优先队列的首选数据结构,其入队和出队操作的时间复杂度均为 <span class="arithmatex">\(O(\log n)\)</span> ,而建队操作为 <span class="arithmatex">\(O(n)\)</span> ,这些操作都非常高效。</li>
<li><strong>堆排序</strong>:给定一组数据,我们可以用它们建立一个堆,然后不断地执行元素出堆操作,从而得到有序数据。然而,我们通常会使用一种更优雅的方式实现堆排序,详见“堆排序”章节。</li>
+2 -2
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3460,7 +3460,7 @@
<ul>
<li><a href="https://www.hello-algo.com/chapter_heap/heap/">8.1 &nbsp;</a></li>
<li><a href="https://www.hello-algo.com/chapter_heap/build_heap/">8.2 &nbsp; 建堆操作</a></li>
<li><a href="https://www.hello-algo.com/chapter_heap/top_k/">8.3 &nbsp; Top-K 问题</a></li>
<li><a href="https://www.hello-algo.com/chapter_heap/top_k/">8.3 &nbsp; Top-k 问题</a></li>
<li><a href="https://www.hello-algo.com/chapter_heap/summary/">8.4 &nbsp; 小结</a></li>
</ul>
+7 -7
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3523,12 +3523,12 @@
<li>完全二叉树非常适合用数组表示,因此我们通常使用数组来存储堆。</li>
<li>堆化操作用于维护堆的性质,在入堆和出堆操作中都会用到。</li>
<li>输入 <span class="arithmatex">\(n\)</span> 个元素并建堆的时间复杂度可以优化至 <span class="arithmatex">\(O(n)\)</span> ,非常高效。</li>
<li>Top-K 是一个经典算法问题,可以使用堆数据结构高效解决,时间复杂度为 <span class="arithmatex">\(O(n \log k)\)</span></li>
<li>Top-k 是一个经典算法问题,可以使用堆数据结构高效解决,时间复杂度为 <span class="arithmatex">\(O(n \log k)\)</span></li>
</ul>
<h3 id="2-q-a">2. &nbsp; Q &amp; A<a class="headerlink" href="#2-q-a" title="Permanent link">&para;</a></h3>
<div class="admonition question">
<p class="admonition-title">数据结构的“堆”与内存管理的“堆”是同一个概念吗?</p>
<p>两者不是同一个概念,只是碰巧都叫。计算机系统内存中的堆是动态内存分配的一部分,程序在运行时可以使用它来存储数据。程序可以请求一定量的堆内存,用于存储如对象和数组等复杂结构。当这些数据不再需要时,程序需要释放这些内存,以防止内存泄漏。相较于栈内存,堆内存的管理和使用需要更谨慎,使用不当可能会导致内存泄漏和野指针等问题。</p>
<p>两者不是同一个概念,只是碰巧都叫“堆”。计算机系统内存中的堆是动态内存分配的一部分,程序在运行时可以使用它来存储数据。程序可以请求一定量的堆内存,用于存储如对象和数组等复杂结构。当这些数据不再需要时,程序需要释放这些内存,以防止内存泄漏。相较于栈内存,堆内存的管理和使用需要更谨慎,使用不当可能会导致内存泄漏和野指针等问题。</p>
</div>
<!-- Source file information -->
@@ -3552,7 +3552,7 @@ aria-label="页脚"
<a
href="../top_k/"
class="md-footer__link md-footer__link--prev"
aria-label="上一页: 8.3 &amp;nbsp; Top-K 问题"
aria-label="上一页: 8.3 &amp;nbsp; Top-k 问题"
rel="prev"
>
<div class="md-footer__button md-icon">
@@ -3564,7 +3564,7 @@ aria-label="页脚"
上一页
</span>
<div class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</div>
</div>
</a>
@@ -3677,7 +3677,7 @@ aria-label="页脚"
<nav class="md-footer__inner md-grid" aria-label="页脚" >
<a href="../top_k/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 8.3 &amp;nbsp; Top-K 问题">
<a href="../top_k/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 8.3 &amp;nbsp; Top-k 问题">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11h12Z"/></svg>
@@ -3687,7 +3687,7 @@ aria-label="页脚"
上一页
</span>
<div class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</div>
</div>
</a>
+8 -8
View File
@@ -26,7 +26,7 @@
<title>8.3   Top-K 问题 - Hello 算法</title>
<title>8.3   Top-k 问题 - Hello 算法</title>
@@ -126,7 +126,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
</div>
@@ -1730,7 +1730,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1741,7 +1741,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3532,10 +3532,10 @@
<!-- Page content -->
<h1 id="83-top-k">8.3 &nbsp; Top-K 问题<a class="headerlink" href="#83-top-k" title="Permanent link">&para;</a></h1>
<h1 id="83-top-k">8.3 &nbsp; Top-k 问题<a class="headerlink" href="#83-top-k" title="Permanent link">&para;</a></h1>
<div class="admonition question">
<p class="admonition-title">Question</p>
<p>给定一个长度为 <span class="arithmatex">\(n\)</span> 的无序数组 <code>nums</code> ,请返回数组中 <span class="arithmatex">\(k\)</span> 大的元素。</p>
<p>给定一个长度为 <span class="arithmatex">\(n\)</span> 的无序数组 <code>nums</code> ,请返回数组中最大的 <span class="arithmatex">\(k\)</span> 元素。</p>
</div>
<p>对于该问题,我们先介绍两种思路比较直接的解法,再介绍效率更高的堆解法。</p>
<h2 id="831">8.3.1 &nbsp; 方法一:遍历选择<a class="headerlink" href="#831" title="Permanent link">&para;</a></h2>
@@ -3555,7 +3555,7 @@
<p align="center"> 图 8-7 &nbsp; 排序寻找最大的 k 个元素 </p>
<h2 id="833">8.3.3 &nbsp; 方法三:堆<a class="headerlink" href="#833" title="Permanent link">&para;</a></h2>
<p>我们可以基于堆更加高效地解决 Top-K 问题,流程如图 8-8 所示。</p>
<p>我们可以基于堆更加高效地解决 Top-k 问题,流程如图 8-8 所示。</p>
<ol>
<li>初始化一个小顶堆,其堆顶元素最小。</li>
<li>先将数组的前 <span class="arithmatex">\(k\)</span> 个元素依次入堆。</li>
@@ -3920,7 +3920,7 @@
</div>
</div>
<p>总共执行了 <span class="arithmatex">\(n\)</span> 轮入堆和出堆,堆的最大长度为 <span class="arithmatex">\(k\)</span> ,因此时间复杂度为 <span class="arithmatex">\(O(n \log k)\)</span> 。该方法的效率很高,当 <span class="arithmatex">\(k\)</span> 较小时,时间复杂度趋向 <span class="arithmatex">\(O(n)\)</span> ;当 <span class="arithmatex">\(k\)</span> 较大时,时间复杂度不会超过 <span class="arithmatex">\(O(n \log n)\)</span></p>
<p>另外,该方法适用于动态数据流的使用场景。在不断加入数据时,我们可以持续维护堆内的元素,从而实现最大 <span class="arithmatex">\(k\)</span> 个元素的动态更新。</p>
<p>另外,该方法适用于动态数据流的使用场景。在不断加入数据时,我们可以持续维护堆内的元素,从而实现最大 <span class="arithmatex">\(k\)</span> 个元素的动态更新。</p>
<!-- Source file information -->
@@ -1731,7 +1731,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3443,7 +3443,7 @@
<h1 id="11">1.1 &nbsp; 算法无处不在<a class="headerlink" href="#11" title="Permanent link">&para;</a></h1>
<p>当我们听到“算法”这个词时,很自然地会想到数学。然而实际上,许多算法并不涉及复杂数学,而是更多地依赖基本逻辑,这些逻辑在我们的日常生活中处处可见。</p>
<p>在正式探讨算法之前,有一个有趣的事实值得分享:<strong>你已经在不知不觉中学会了许多算法,并习惯将它们应用到日常生活中了</strong>。下面我将举几个具体的例子来证实这一点。</p>
<p><strong>例一:查字典</strong>。在字典里,每个汉字都对应一个拼音,而字典是按照拼音字母顺序排列的。假设我们需要查找一个拼音首字母为 <span class="arithmatex">\(r\)</span> 的字,通常会按照图 1-1 所示的方式实现。</p>
<p><strong>例一:查字典</strong>。在字典里,每个汉字都对应一个拼音,而字典是按照拼音字母顺序排列的。假设我们需要查找一个拼音首字母为 <span class="arithmatex">\(r\)</span> 的字,通常会按照图 1-1 所示的方式实现。</p>
<ol>
<li>翻开字典约一半的页数,查看该页的首字母是什么,假设首字母为 <span class="arithmatex">\(m\)</span></li>
<li>由于在拼音字母表中 <span class="arithmatex">\(r\)</span> 位于 <span class="arithmatex">\(m\)</span> 之后,所以排除字典前半部分,查找范围缩小到后半部分。</li>
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+2 -2
View File
@@ -1731,7 +1731,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3443,7 +3443,7 @@
<h1 id="13">1.3 &nbsp; 小结<a class="headerlink" href="#13" title="Permanent link">&para;</a></h1>
<ul>
<li>算法在日常生活中无处不在,并不是遥不可及的高深知识。实际上,我们已经在不知不觉中学会了许多算法,用以解决生活中的大小问题。</li>
<li>字典的原理与二分查找算法相一致。二分查找算法体现了分而治之的重要算法思想。</li>
<li>查字典的原理与二分查找算法相一致。二分查找算法体现了分而治之的重要算法思想。</li>
<li>整理扑克的过程与插入排序算法非常类似。插入排序算法适合排序小型数据集。</li>
<li>货币找零的步骤本质上是贪心算法,每一步都采取当前看来最好的选择。</li>
<li>算法是在有限时间内解决特定问题的一组指令或操作步骤,而数据结构是计算机中组织和存储数据的方式。</li>
+1 -1
View File
@@ -1788,7 +1788,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+14 -14
View File
@@ -1788,7 +1788,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3533,16 +3533,16 @@
<!-- Page content -->
<h1 id="01">0.1 &nbsp; 关于本书<a class="headerlink" href="#01" title="Permanent link">&para;</a></h1>
<p>本项目旨在创建一本开源、免费、新手友好的数据结构与算法入门教程。</p>
<p>本项目旨在创建一本开源、免费、新手友好的数据结构与算法入门教程。</p>
<ul>
<li>全书采用动画图解,结构化地讲解数据结构与算法知识,内容清晰易懂学习曲线平滑。</li>
<li>算法源代码皆可一键运行,支持 Python、C++、Java、C#、Go、Swift、JavaScript、TypeScript、Dart、Rust、CZig 等语言。</li>
<li>鼓励读者在章节论区互帮互助、共同进步,提问与评论通常可在两日内得到回复。</li>
<li>全书采用动画图解,结构化地讲解数据结构与算法知识,内容清晰易懂学习曲线平滑。</li>
<li>算法源代码皆可一键运行,支持 Python、C++、Java、C#、Go、Swift、JavaScript、TypeScript、Dart、Rust、CZig 等语言。</li>
<li>鼓励读者在线上章节论区互帮互助、共同进步,提问与评论通常可在两日内得到回复。</li>
</ul>
<h2 id="011">0.1.1 &nbsp; 读者对象<a class="headerlink" href="#011" title="Permanent link">&para;</a></h2>
<p>若你是算法初学者,从未接触过算法,或者已经有一些刷题经验,对数据结构与算法有模糊的认识,在会与不会之间反复横跳,那么本书正是为你量身定制的!</p>
<p>如果你已经积累一定刷题量,熟悉大部分题型,那么本书可助你回顾与梳理算法知识体系,仓库源代码可以当作“刷题工具库”或“算法字典”来使用。</p>
<p>若你是算法大神,我们期待收到你的宝贵建议,或者<a href="https://www.hello-algo.com/chapter_appendix/contribution/">一起参与创作</a></p>
<p>如果你已经积累一定刷题量,熟悉大部分题型,那么本书可助你回顾与梳理算法知识体系,仓库源代码可以当作“刷题工具库”或“算法字典”来使用。</p>
<p>若你是算法大神,我们期待收到你的宝贵建议,或者<a href="https://www.hello-algo.com/chapter_appendix/contribution/">一起参与创作</a></p>
<div class="admonition success">
<p class="admonition-title">前置条件</p>
<p>你需要至少具备任一语言的编程基础,能够阅读和编写简单代码。</p>
@@ -3550,25 +3550,25 @@
<h2 id="012">0.1.2 &nbsp; 内容结构<a class="headerlink" href="#012" title="Permanent link">&para;</a></h2>
<p>本书的主要内容如图 0-1 所示。</p>
<ul>
<li><strong>复杂度分析</strong>:数据结构和算法的评价维度与方法。时间复杂度空间复杂度的推算方法、常见类型、示例等。</li>
<li><strong>数据结构</strong>:基本数据类型数据结构的分类方法。数组、链表、栈、队列、哈希表、树、堆、图等数据结构的定义、优缺点、常用操作、常见类型、典型应用、实现方法等。</li>
<li><strong>复杂度分析</strong>:数据结构和算法的评价维度与方法。时间复杂度空间复杂度的推算方法、常见类型、示例等。</li>
<li><strong>数据结构</strong>:基本数据类型数据结构的分类方法。数组、链表、栈、队列、哈希表、树、堆、图等数据结构的定义、优缺点、常用操作、常见类型、典型应用、实现方法等。</li>
<li><strong>算法</strong>:搜索、排序、分治、回溯、动态规划、贪心等算法的定义、优缺点、效率、应用场景、解题步骤和示例问题等。</li>
</ul>
<p><a class="glightbox" href="../about_the_book.assets/hello_algo_mindmap.jpg" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="本书主要内容" class="animation-figure" src="../about_the_book.assets/hello_algo_mindmap.jpg" /></a></p>
<p align="center"> 图 0-1 &nbsp; 本书主要内容 </p>
<h2 id="013">0.1.3 &nbsp; 致谢<a class="headerlink" href="#013" title="Permanent link">&para;</a></h2>
<p>在本书的创作过程中,我得到了许多人的帮助,包括但不限于:</p>
<p>在本书的创作过程中,我得到了许多人的帮助</p>
<ul>
<li>感谢我在公司的导师李汐博士,在一次畅谈中你鼓励我“快行动起来”,坚定了我写这本书的决心;</li>
<li>感谢我的女朋友泡泡作为本书的首位读者,从算法小白的角度提出许多宝贵建议,使得本书更适合新手阅读;</li>
<li>感谢腾宝、琦宝、飞宝为本书起了一个富有创意的名字,唤起大家写下第一行代码 "Hello World!" 的美好回忆;</li>
<li>感谢校铨在知识产权方面提供的专业帮助,这对本开源书的发展起到了重要作用;</li>
<li>感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症下多次耐心修改;</li>
<li>感谢 @squidfunk 提供的写作排版建议,以及他开发的开源文档主题 <a href="https://github.com/squidfunk/mkdocs-material/tree/master">Material-for-MkDocs</a></li>
<li>感谢校铨在知识产权方面提供的专业帮助,这对本开源书的完善起到了重要作用;</li>
<li>感谢苏潼为本书设计了精美的封面和 logo ,并在我的强迫症的驱使下多次耐心修改;</li>
<li>感谢 @squidfunk 提供的排版建议,以及他开发的开源文档主题 <a href="https://github.com/squidfunk/mkdocs-material/tree/master">Material-for-MkDocs</a></li>
</ul>
<p>在写作过程中,我阅读了许多关于数据结构与算法的教材和文章。这些作品为本书提供了优秀的范本,确保了本书内容的准确性与品质。在此感谢所有老师和前辈们的杰出贡献!</p>
<p>本书倡导手脑并用的学习方式,在这一点上深受<a href="https://github.com/d2l-ai/d2l-zh">《动手学深度学习》</a>的启发。在此向各位读者强烈推荐这本优秀的著作。</p>
<p>本书倡导手脑并用的学习方式,在这一点上深受<a href="https://github.com/d2l-ai/d2l-zh">《动手学深度学习》</a>的启发。在此向各位读者强烈推荐这本优秀的著作。</p>
<p><strong>衷心感谢我的父母,正是你们一直以来的支持与鼓励,让我有机会做这件富有趣味的事</strong></p>
<!-- Source file information -->
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+5 -5
View File
@@ -1806,7 +1806,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3578,8 +3578,8 @@
<li>标题后标注 <code>*</code> 的是选读章节,内容相对困难。如果你的时间有限,可以先跳过。</li>
<li>重要专有名词及其英文翻译会用 <code>「 」</code> 括号标注,例如 <code>「数组 array」</code> 。建议记住它们,以便阅读文献。</li>
<li>专有名词和有特指含义的词句会使用 <code>“引号”</code> 标注,以避免歧义。</li>
<li>重要名词、重点内容和总结性语句会 <strong>加粗</strong> ,这类文字值得特别关注。</li>
<li>当涉及编程语言之间不一致的名词时,本书均以 Python 为准,例如使用 <span class="arithmatex">\(\text{None}\)</span> 来表示“空”。</li>
<li>重要名词、重点内容和总结性语句会 <strong>加粗</strong> ,这类文字值得特别关注。</li>
<li>当涉及编程语言之间不一致的名词时,本书均以 Python 为准,例如使用 <code>None</code> 来表示“空”。</li>
<li>本书部分放弃了编程语言的注释规范,以换取更加紧凑的内容排版。注释主要分为三种类型:标题注释、内容注释、多行注释。</li>
</ul>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
@@ -3717,7 +3717,7 @@
</div>
</div>
<h2 id="022">0.2.2 &nbsp; 在动画图解中高效学习<a class="headerlink" href="#022" title="Permanent link">&para;</a></h2>
<p>相较于文字,视频和图片具有更高的信息密度和结构化程度,更易于理解。在本书中,<strong>重点和难点知识将主要通过动画图解形式展示</strong>,而文字则作为动画和图片的解释与补充。</p>
<p>相较于文字,视频和图片具有更高的信息密度和结构化程度,更易于理解。在本书中,<strong>重点和难点知识将主要通过动画图解形式展示</strong>,而文字则作为解释与补充。</p>
<p>如果你在阅读本书时,发现某段内容提供了如图 0-2 所示的动画或图解,<strong>请以图为主、以文字为辅</strong>,综合两者来理解内容。</p>
<p><a class="glightbox" href="../../index.assets/animation.gif" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="动画图解示例" class="animation-figure" src="../../index.assets/animation.gif" /></a></p>
<p align="center"> 图 0-2 &nbsp; 动画图解示例 </p>
@@ -3745,7 +3745,7 @@
<h2 id="024">0.2.4 &nbsp; 在提问讨论中共同成长<a class="headerlink" href="#024" title="Permanent link">&para;</a></h2>
<p>在阅读本书时,请不要轻易跳过那些没学明白的知识点。<strong>欢迎在评论区提出你的问题</strong>,我和小伙伴们将竭诚为你解答,一般情况下可在两天内回复。</p>
<p>如图 0-6 所示,每个章节的底部都配有评论区。希望你能多关注评论区的内容。一方面,你可以了解大家遇到的问题,从而查漏补缺,激发更深入的思考。另一方面,期待你能慷慨地回答其他小伙伴的问题,分享你的见解,帮助他人进步。</p>
<p>如图 0-6 所示,网页版每个章节的底部都配有评论区。希望你能多关注评论区的内容。一方面,你可以了解大家遇到的问题,从而查漏补缺,激发更深入的思考。另一方面,期待你能慷慨地回答其他小伙伴的问题,分享你的见解,帮助他人进步。</p>
<p><a class="glightbox" href="../../index.assets/comment.gif" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="评论区示例" class="animation-figure" src="../../index.assets/comment.gif" /></a></p>
<p align="center"> 图 0-6 &nbsp; 评论区示例 </p>
+5 -5
View File
@@ -1731,7 +1731,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3442,12 +3442,12 @@
<!-- Page content -->
<h1 id="03">0.3 &nbsp; 小结<a class="headerlink" href="#03" title="Permanent link">&para;</a></h1>
<ul>
<li>本书的主要受众是算法初学者。如果已有一定基础,本书能帮助你系统回顾算法知识,书中源代码也可作为“刷题工具库”使用。</li>
<li>书中内容主要包括复杂度分析、数据结构算法三部分,涵盖了该领域的大部分主题。</li>
<li>本书的主要受众是算法初学者。如果已有一定基础,本书能帮助你系统回顾算法知识,书中源代码也可作为“刷题工具库”使用。</li>
<li>书中内容主要包括复杂度分析、数据结构算法三部分,涵盖了该领域的大部分主题。</li>
<li>对于算法新手,在初学阶段阅读一本入门书至关重要,可以少走许多弯路。</li>
<li>书中的动画图解通常用于介绍重点和难点知识。阅读本书时,应给予这些内容更多关注。</li>
<li>书中的动画图解通常用于介绍重点和难点知识。阅读本书时,应给予这些内容更多关注。</li>
<li>实践乃学习编程之最佳途径。强烈建议运行源代码并亲自敲代码。</li>
<li>本书网页版的每个章节都设有论区,欢迎随时分享你的疑惑与见解。</li>
<li>本书网页版的每个章节都设有论区,欢迎随时分享你的疑惑与见解。</li>
</ul>
<!-- Source file information -->
+1 -1
View File
@@ -1717,7 +1717,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+3 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3825,8 +3825,8 @@
</div>
</div>
</div>
<p><strong>时间复杂度 <span class="arithmatex">\(O(\log n)\)</span></strong> :在二分循环中,区间每轮缩小一半,循环次数为 <span class="arithmatex">\(\log_2 n\)</span></p>
<p><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span></strong> :指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小空间。</p>
<p><strong>时间复杂度 <span class="arithmatex">\(O(\log n)\)</span></strong> :在二分循环中,区间每轮缩小一半,循环次数为 <span class="arithmatex">\(\log_2 n\)</span></p>
<p><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span></strong> :指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小空间。</p>
<h2 id="1011">10.1.1 &nbsp; 区间表示方法<a class="headerlink" href="#1011" title="Permanent link">&para;</a></h2>
<p>除了上述双闭区间外,常见的区间表示还有“左闭右开”区间,定义为 <span class="arithmatex">\([0, n)\)</span> ,即左边界包含自身,右边界不包含自身。在该表示下,区间 <span class="arithmatex">\([i, j)\)</span><span class="arithmatex">\(i = j\)</span> 时为空。</p>
<p>我们可以基于该表示实现具有相同功能的二分查找算法:</p>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3940,7 +3940,7 @@
<p>代码在此省略,以下两点值得注意。</p>
<ul>
<li>给定数组不包含小数,这意味着我们无须关心如何处理相等的情况。</li>
<li>因为该方法引入了小数,所以需要将函数中的变量 <code>target</code> 改为浮点数类型。</li>
<li>因为该方法引入了小数,所以需要将函数中的变量 <code>target</code> 改为浮点数类型Python 无须改动)</li>
</ul>
<!-- Source file information -->
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3519,7 +3519,7 @@
<h2 id="1021">10.2.1 &nbsp; 无重复元素的情况<a class="headerlink" href="#1021" title="Permanent link">&para;</a></h2>
<div class="admonition question">
<p class="admonition-title">Question</p>
<p>给定一个长度为 <span class="arithmatex">\(n\)</span> 的有序数组 <code>nums</code> 和一个元素 <code>target</code> ,数组不存在重复元素。现将 <code>target</code> 插入数组 <code>nums</code> 中,并保持其有序性。若数组中已存在元素 <code>target</code> ,则插入到其左方。请返回插入后 <code>target</code> 在数组中的索引。</p>
<p>给定一个长度为 <span class="arithmatex">\(n\)</span> 的有序数组 <code>nums</code> 和一个元素 <code>target</code> ,数组不存在重复元素。现将 <code>target</code> 插入数组 <code>nums</code> 中,并保持其有序性。若数组中已存在元素 <code>target</code> ,则插入到其左方。请返回插入后 <code>target</code> 在数组中的索引。示例如图 10-4 所示。</p>
</div>
<p><a class="glightbox" href="../binary_search_insertion.assets/binary_search_insertion_example.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="二分查找插入点示例数据" class="animation-figure" src="../binary_search_insertion.assets/binary_search_insertion_example.png" /></a></p>
<p align="center"> 图 10-4 &nbsp; 二分查找插入点示例数据 </p>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3651,7 +3651,7 @@
<li>适用于海量数据,因为树节点在内存中是分散存储的。</li>
<li>适合需要维护有序数据或范围查找的场景。</li>
<li>在持续增删节点的过程中,二叉搜索树可能产生倾斜,时间复杂度劣化至 <span class="arithmatex">\(O(n)\)</span></li>
<li>若使用 AVL 树或红黑树,则各项操作可在 <span class="arithmatex">\(O(\log n)\)</span> 效率下稳定运行,但维护树平衡的操作会增加额外开销。</li>
<li>若使用 AVL 树或红黑树,则各项操作可在 <span class="arithmatex">\(O(\log n)\)</span> 效率下稳定运行,但维护树平衡的操作会增加额外开销。</li>
</ul>
<!-- Source file information -->
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+13 -13
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3565,7 +3565,7 @@
<h2 id="1131">11.3.1 &nbsp; 算法流程<a class="headerlink" href="#1131" title="Permanent link">&para;</a></h2>
<p>设数组的长度为 <span class="arithmatex">\(n\)</span> ,冒泡排序的步骤如图 11-5 所示。</p>
<ol>
<li>首先,对 <span class="arithmatex">\(n\)</span> 个元素执行“冒泡”,<strong>将数组的最大元素交换至正确位置</strong></li>
<li>首先,对 <span class="arithmatex">\(n\)</span> 个元素执行“冒泡”,<strong>将数组的最大元素交换至正确位置</strong></li>
<li>接下来,对剩余 <span class="arithmatex">\(n - 1\)</span> 个元素执行“冒泡”,<strong>将第二大元素交换至正确位置</strong></li>
<li>以此类推,经过 <span class="arithmatex">\(n - 1\)</span> 轮“冒泡”后,<strong><span class="arithmatex">\(n - 1\)</span> 大的元素都被交换至正确位置</strong></li>
<li>仅剩的一个元素必定是最小元素,无须排序,因此数组排序完成。</li>
@@ -3804,7 +3804,7 @@
<a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span> <span class="o">+</span> <span class="mi">1</span><span class="p">],</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span>
<a id="__codelineno-12-12" name="__codelineno-12-12" href="#__codelineno-12-12"></a> <span class="n">flag</span> <span class="o">=</span> <span class="kc">True</span> <span class="c1"># 记录交换元素</span>
<a id="__codelineno-12-13" name="__codelineno-12-13" href="#__codelineno-12-13"></a> <span class="k">if</span> <span class="ow">not</span> <span class="n">flag</span><span class="p">:</span>
<a id="__codelineno-12-14" name="__codelineno-12-14" href="#__codelineno-12-14"></a> <span class="k">break</span> <span class="c1"># 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-12-14" name="__codelineno-12-14" href="#__codelineno-12-14"></a> <span class="k">break</span> <span class="c1"># 此轮冒泡未交换任何元素,直接跳出</span>
</code></pre></div>
</div>
<div class="tabbed-block">
@@ -3823,7 +3823,7 @@
<a id="__codelineno-13-13" name="__codelineno-13-13" href="#__codelineno-13-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-14" name="__codelineno-13-14" href="#__codelineno-13-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-15" name="__codelineno-13-15" href="#__codelineno-13-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span>
<a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-13-16" name="__codelineno-13-16" href="#__codelineno-13-16"></a><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-13-17" name="__codelineno-13-17" href="#__codelineno-13-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-13-18" name="__codelineno-13-18" href="#__codelineno-13-18"></a><span class="p">}</span>
</code></pre></div>
@@ -3845,7 +3845,7 @@
<a id="__codelineno-14-14" name="__codelineno-14-14" href="#__codelineno-14-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-15" name="__codelineno-14-15" href="#__codelineno-14-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-16" name="__codelineno-14-16" href="#__codelineno-14-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span>
<a id="__codelineno-14-17" name="__codelineno-14-17" href="#__codelineno-14-17"></a><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-14-17" name="__codelineno-14-17" href="#__codelineno-14-17"></a><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-14-18" name="__codelineno-14-18" href="#__codelineno-14-18"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-14-19" name="__codelineno-14-19" href="#__codelineno-14-19"></a><span class="p">}</span>
</code></pre></div>
@@ -3864,7 +3864,7 @@
<a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">true</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a><span class="p">}</span>
</code></pre></div>
@@ -3883,7 +3883,7 @@
<a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">false</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a><span class="w"> </span><span class="k">break</span>
<a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-16-17" name="__codelineno-16-17" href="#__codelineno-16-17"></a><span class="w"> </span><span class="p">}</span>
@@ -3905,7 +3905,7 @@
<a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a> <span class="n">flag</span> <span class="p">=</span> <span class="kc">true</span> <span class="c1">// 记录交换元素</span>
<a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a> <span class="p">}</span>
<a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a> <span class="p">}</span>
<a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a> <span class="k">if</span> <span class="o">!</span><span class="n">flag</span> <span class="p">{</span> <span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a> <span class="k">if</span> <span class="o">!</span><span class="n">flag</span> <span class="p">{</span> <span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-17-16" name="__codelineno-17-16" href="#__codelineno-17-16"></a> <span class="k">break</span>
<a id="__codelineno-17-17" name="__codelineno-17-17" href="#__codelineno-17-17"></a> <span class="p">}</span>
<a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a> <span class="p">}</span>
@@ -3928,7 +3928,7 @@
<a id="__codelineno-18-13" name="__codelineno-18-13" href="#__codelineno-18-13"></a><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-18-14" name="__codelineno-18-14" href="#__codelineno-18-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-15" name="__codelineno-18-15" href="#__codelineno-18-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-18-16" name="__codelineno-18-16" href="#__codelineno-18-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-18-17" name="__codelineno-18-17" href="#__codelineno-18-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-18-18" name="__codelineno-18-18" href="#__codelineno-18-18"></a><span class="p">}</span>
</code></pre></div>
@@ -3949,7 +3949,7 @@
<a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a><span class="w"> </span><span class="nx">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a><span class="p">}</span>
</code></pre></div>
@@ -3970,7 +3970,7 @@
<a id="__codelineno-20-13" name="__codelineno-20-13" href="#__codelineno-20-13"></a><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-20-14" name="__codelineno-20-14" href="#__codelineno-20-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-15" name="__codelineno-20-15" href="#__codelineno-20-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-16" name="__codelineno-20-16" href="#__codelineno-20-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-20-16" name="__codelineno-20-16" href="#__codelineno-20-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-20-17" name="__codelineno-20-17" href="#__codelineno-20-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-20-18" name="__codelineno-20-18" href="#__codelineno-20-18"></a><span class="p">}</span>
</code></pre></div>
@@ -3991,7 +3991,7 @@
<a id="__codelineno-21-13" name="__codelineno-21-13" href="#__codelineno-21-13"></a><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span><span class="w"> </span><span class="c1">// 记录交换元素</span>
<a id="__codelineno-21-14" name="__codelineno-21-14" href="#__codelineno-21-14"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-15" name="__codelineno-21-15" href="#__codelineno-21-15"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-16" name="__codelineno-21-16" href="#__codelineno-21-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">!</span><span class="n">flag</span><span class="w"> </span><span class="p">{</span><span class="k">break</span><span class="p">};</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-21-16" name="__codelineno-21-16" href="#__codelineno-21-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">!</span><span class="n">flag</span><span class="w"> </span><span class="p">{</span><span class="k">break</span><span class="p">};</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-21-17" name="__codelineno-21-17" href="#__codelineno-21-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-21-18" name="__codelineno-21-18" href="#__codelineno-21-18"></a><span class="p">}</span>
</code></pre></div>
@@ -4035,7 +4035,7 @@
<a id="__codelineno-23-15" name="__codelineno-23-15" href="#__codelineno-23-15"></a><span class="w"> </span><span class="n">flag</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">true</span><span class="p">;</span>
<a id="__codelineno-23-16" name="__codelineno-23-16" href="#__codelineno-23-16"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-23-17" name="__codelineno-23-17" href="#__codelineno-23-17"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-23-18" name="__codelineno-23-18" href="#__codelineno-23-18"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-23-18" name="__codelineno-23-18" href="#__codelineno-23-18"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="n">flag</span><span class="p">)</span><span class="w"> </span><span class="k">break</span><span class="p">;</span><span class="w"> </span><span class="c1">// 此轮冒泡未交换任何元素,直接跳出</span>
<a id="__codelineno-23-19" name="__codelineno-23-19" href="#__codelineno-23-19"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-23-20" name="__codelineno-23-20" href="#__codelineno-23-20"></a><span class="p">}</span>
</code></pre></div>
+3 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3901,9 +3901,9 @@
<h2 id="1182">11.8.2 &nbsp; 算法特性<a class="headerlink" href="#1182" title="Permanent link">&para;</a></h2>
<p>桶排序适用于处理体量很大的数据。例如,输入数据包含 100 万个元素,由于空间限制,系统内存无法一次性加载所有数据。此时,可以将数据分成 1000 个桶,然后分别对每个桶进行排序,最后将结果合并。</p>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n + k)\)</span></strong> :假设元素在各个桶内平均分布,那么每个桶内的元素数量为 <span class="arithmatex">\(\frac{n}{k}\)</span> 。假设排序单个桶使用 <span class="arithmatex">\(O(\frac{n}{k} \log\frac{n}{k})\)</span> 时间,则排序所有桶使用 <span class="arithmatex">\(O(n \log\frac{n}{k})\)</span> 时间。<strong>当桶数量 <span class="arithmatex">\(k\)</span> 比较大时,时间复杂度则趋向于 <span class="arithmatex">\(O(n)\)</span></strong> 。合并结果时需要遍历所有桶和元素,花费 <span class="arithmatex">\(O(n + k)\)</span> 时间。</li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n + k)\)</span></strong> :假设元素在各个桶内平均分布,那么每个桶内的元素数量为 <span class="arithmatex">\(\frac{n}{k}\)</span> 。假设排序单个桶使用 <span class="arithmatex">\(O(\frac{n}{k} \log\frac{n}{k})\)</span> 时间,则排序所有桶使用 <span class="arithmatex">\(O(n \log\frac{n}{k})\)</span> 时间。<strong>当桶数量 <span class="arithmatex">\(k\)</span> 比较大时,时间复杂度则趋向于 <span class="arithmatex">\(O(n)\)</span></strong> 。合并结果时需要遍历所有桶和元素,花费 <span class="arithmatex">\(O(n + k)\)</span> 时间。</li>
<li><strong>自适应排序</strong>:在最差情况下,所有数据被分配到一个桶中,且排序该桶使用 <span class="arithmatex">\(O(n^2)\)</span> 时间。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + k)\)</span>、非原地排序</strong>:需要借助 <span class="arithmatex">\(k\)</span> 个桶和总共 <span class="arithmatex">\(n\)</span> 个元素的额外空间。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + k)\)</span>、非原地排序</strong>:需要借助 <span class="arithmatex">\(k\)</span> 个桶和总共 <span class="arithmatex">\(n\)</span> 个元素的额外空间。</li>
<li>桶排序是否稳定取决于排序桶内元素的算法是否稳定。</li>
</ul>
<h2 id="1183">11.8.3 &nbsp; 如何实现平均分配<a class="headerlink" href="#1183" title="Permanent link">&para;</a></h2>
+3 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4281,8 +4281,8 @@
</div>
<h2 id="1193">11.9.3 &nbsp; 算法特性<a class="headerlink" href="#1193" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n + m)\)</span></strong> :涉及遍历 <code>nums</code> 和遍历 <code>counter</code> ,都使用线性时间。一般情况下 <span class="arithmatex">\(n \gg m\)</span> ,时间复杂度趋于 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + m)\)</span>、非原地排序</strong>:借助了长度分别为 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(m\)</span> 的数组 <code>res</code><code>counter</code></li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n + m)\)</span></strong> :涉及遍历 <code>nums</code> 和遍历 <code>counter</code> ,都使用线性时间。一般情况下 <span class="arithmatex">\(n \gg m\)</span> ,时间复杂度趋于 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + m)\)</span>、非原地排序</strong>:借助了长度分别为 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(m\)</span> 的数组 <code>res</code><code>counter</code></li>
<li><strong>稳定排序</strong>:由于向 <code>res</code> 中填充元素的顺序是“从右向左”的,因此倒序遍历 <code>nums</code> 可以避免改变相等元素之间的相对位置,从而实现稳定排序。实际上,正序遍历 <code>nums</code> 也可以得到正确的排序结果,但结果是非稳定的。</li>
</ul>
<h2 id="1194">11.9.4 &nbsp; 局限性<a class="headerlink" href="#1194" title="Permanent link">&para;</a></h2>
+3 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4036,8 +4036,8 @@
</div>
<h2 id="1172">11.7.2 &nbsp; 算法特性<a class="headerlink" href="#1172" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、非自适应排序</strong>:建堆操作使用 <span class="arithmatex">\(O(n)\)</span> 时间。从堆中提取最大元素的时间复杂度为 <span class="arithmatex">\(O(\log n)\)</span> ,共循环 <span class="arithmatex">\(n - 1\)</span> 轮。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:几个指针变量使用 <span class="arithmatex">\(O(1)\)</span> 空间。元素交换和堆化操作都是在原数组上进行的。</li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、非自适应排序</strong>:建堆操作使用 <span class="arithmatex">\(O(n)\)</span> 时间。从堆中提取最大元素的时间复杂度为 <span class="arithmatex">\(O(\log n)\)</span> ,共循环 <span class="arithmatex">\(n - 1\)</span> 轮。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:几个指针变量使用 <span class="arithmatex">\(O(1)\)</span> 空间。元素交换和堆化操作都是在原数组上进行的。</li>
<li><strong>非稳定排序</strong>:在交换堆顶元素和堆底元素时,相等元素的相对位置可能发生变化。</li>
</ul>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+6 -6
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -2326,7 +2326,7 @@
<li class="md-nav__item">
<a href="#1143" class="md-nav__link">
<span class="md-ellipsis">
11.4.3 &nbsp; 插入排序优势
11.4.3 &nbsp; 插入排序优势
</span>
</a>
@@ -3490,7 +3490,7 @@
<li class="md-nav__item">
<a href="#1143" class="md-nav__link">
<span class="md-ellipsis">
11.4.3 &nbsp; 插入排序优势
11.4.3 &nbsp; 插入排序优势
</span>
</a>
@@ -3754,11 +3754,11 @@
</div>
<h2 id="1142">11.4.2 &nbsp; 算法特性<a class="headerlink" href="#1142" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n^2)\)</span>、自适应排序</strong>:在最差情况下,每次插入操作分别需要循环 <span class="arithmatex">\(n - 1\)</span><span class="arithmatex">\(n-2\)</span><span class="arithmatex">\(\dots\)</span><span class="arithmatex">\(2\)</span><span class="arithmatex">\(1\)</span> 次,求和得到 <span class="arithmatex">\((n - 1) n / 2\)</span> ,因此时间复杂度为 <span class="arithmatex">\(O(n^2)\)</span> 。在遇到有序数据时,插入操作会提前终止。当输入数组完全有序时,插入排序达到最佳时间复杂度 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小的额外空间。</li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n^2)\)</span>、自适应排序</strong>:在最差情况下,每次插入操作分别需要循环 <span class="arithmatex">\(n - 1\)</span><span class="arithmatex">\(n-2\)</span><span class="arithmatex">\(\dots\)</span><span class="arithmatex">\(2\)</span><span class="arithmatex">\(1\)</span> 次,求和得到 <span class="arithmatex">\((n - 1) n / 2\)</span> ,因此时间复杂度为 <span class="arithmatex">\(O(n^2)\)</span> 。在遇到有序数据时,插入操作会提前终止。当输入数组完全有序时,插入排序达到最佳时间复杂度 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小的额外空间。</li>
<li><strong>稳定排序</strong>:在插入操作过程中,我们会将元素插入到相等元素的右侧,不会改变它们的顺序。</li>
</ul>
<h2 id="1143">11.4.3 &nbsp; 插入排序优势<a class="headerlink" href="#1143" title="Permanent link">&para;</a></h2>
<h2 id="1143">11.4.3 &nbsp; 插入排序优势<a class="headerlink" href="#1143" title="Permanent link">&para;</a></h2>
<p>插入排序的时间复杂度为 <span class="arithmatex">\(O(n^2)\)</span> ,而我们即将学习的快速排序的时间复杂度为 <span class="arithmatex">\(O(n \log n)\)</span> 。尽管插入排序的时间复杂度更高,<strong>但在数据量较小的情况下,插入排序通常更快</strong></p>
<p>这个结论与线性查找和二分查找的适用情况的结论类似。快速排序这类 <span class="arithmatex">\(O(n \log n)\)</span> 的算法属于基于分治策略的排序算法,往往包含更多单元计算操作。而在数据量较小时,<span class="arithmatex">\(n^2\)</span><span class="arithmatex">\(n \log n\)</span> 的数值比较接近,复杂度不占主导地位;每轮中的单元操作数量起到决定性作用。</p>
<p>实际上,许多编程语言(例如 Java)的内置排序函数采用了插入排序,大致思路为:对于长数组,采用基于分治策略的排序算法,例如快速排序;对于短数组,直接使用插入排序。</p>
+25 -25
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3595,12 +3595,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.py</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="k">def</span> <span class="nf">merge</span><span class="p">(</span><span class="n">nums</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">left</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">mid</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">right</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;合并左子数组和右子数组&quot;&quot;&quot;</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="c1"># 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> <span class="c1"># 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> <span class="c1"># 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> <span class="n">tmp</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">*</span> <span class="p">(</span><span class="n">right</span> <span class="o">-</span> <span class="n">left</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> <span class="c1"># 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> <span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">k</span> <span class="o">=</span> <span class="n">left</span><span class="p">,</span> <span class="n">mid</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span>
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="c1"># 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a> <span class="c1"># 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">mid</span> <span class="ow">and</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="n">right</span><span class="p">:</span>
<a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> <span class="k">if</span> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]:</span>
<a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> <span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="o">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
@@ -3638,12 +3638,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.cpp</span><pre><span></span><code><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="kt">void</span><span class="w"> </span><span class="nf">merge</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="w"> </span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">tmp</span><span class="p">(</span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
<a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a><span class="w"> </span><span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="o">++</span><span class="p">];</span>
@@ -3680,12 +3680,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.java</span><pre><span></span><code><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a><span class="kt">void</span><span class="w"> </span><span class="nf">merge</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a><span class="w"> </span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="o">[</span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="o">]</span><span class="p">;</span>
<a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nums</span><span class="o">[</span><span class="n">i</span><span class="o">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="o">[</span><span class="n">j</span><span class="o">]</span><span class="p">)</span>
<a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a><span class="w"> </span><span class="n">tmp</span><span class="o">[</span><span class="n">k</span><span class="o">++]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="o">[</span><span class="n">i</span><span class="o">++]</span><span class="p">;</span>
@@ -3722,12 +3722,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.cs</span><pre><span></span><code><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="k">void</span><span class="w"> </span><span class="nf">Merge</span><span class="p">(</span><span class="kt">int</span><span class="p">[]</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="w"> </span><span class="kt">int</span><span class="p">[]</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="kt">int</span><span class="p">[</span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">];</span>
<a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span>
<a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
<a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a><span class="w"> </span><span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="o">++</span><span class="p">];</span>
@@ -3763,12 +3763,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.go</span><pre><span></span><code><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="kd">func</span><span class="w"> </span><span class="nx">merge</span><span class="p">(</span><span class="nx">nums</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="nx">tmp</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nb">make</span><span class="p">([]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="o">-</span><span class="nx">left</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="w"> </span><span class="nx">i</span><span class="p">,</span><span class="w"> </span><span class="nx">j</span><span class="p">,</span><span class="w"> </span><span class="nx">k</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span>
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">right</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a><span class="w"> </span><span class="nx">tmp</span><span class="p">[</span><span class="nx">k</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
@@ -3814,12 +3814,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.swift</span><pre><span></span><code><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="kd">func</span> <span class="nf">merge</span><span class="p">(</span><span class="n">nums</span><span class="p">:</span> <span class="kr">inout</span> <span class="p">[</span><span class="nb">Int</span><span class="p">],</span> <span class="kr">left</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="n">mid</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="kr">right</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> <span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> <span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> <span class="kd">var</span> <span class="nv">tmp</span> <span class="p">=</span> <span class="nb">Array</span><span class="p">(</span><span class="n">repeating</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="bp">count</span><span class="p">:</span> <span class="kr">right</span> <span class="o">-</span> <span class="kr">left</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> <span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> <span class="kd">var</span> <span class="nv">i</span> <span class="p">=</span> <span class="kr">left</span><span class="p">,</span> <span class="n">j</span> <span class="p">=</span> <span class="n">mid</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">k</span> <span class="p">=</span> <span class="mi">0</span>
<a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> <span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> <span class="k">while</span> <span class="n">i</span> <span class="o">&lt;=</span> <span class="n">mid</span><span class="p">,</span> <span class="n">j</span> <span class="o">&lt;=</span> <span class="kr">right</span> <span class="p">{</span>
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="k">if</span> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="p">{</span>
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="p">]</span> <span class="p">=</span> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
@@ -3866,14 +3866,14 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.js</span><pre><span></span><code><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="kd">function</span><span class="w"> </span><span class="nx">merge</span><span class="p">(</span><span class="nx">nums</span><span class="p">,</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">);</span>
<a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span>
<a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a><span class="w"> </span><span class="nx">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a><span class="w"> </span><span class="nx">tmp</span><span class="p">[</span><span class="nx">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="o">++</span><span class="p">];</span>
@@ -3910,14 +3910,14 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.ts</span><pre><span></span><code><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="kd">function</span><span class="w"> </span><span class="nx">merge</span><span class="p">(</span><span class="nx">nums</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">[],</span><span class="w"> </span><span class="nx">left</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="ow">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Array</span><span class="p">(</span><span class="nx">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">);</span>
<a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span>
<a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">,</span>
<a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a><span class="w"> </span><span class="nx">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
<a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="nx">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">j</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a><span class="w"> </span><span class="nx">tmp</span><span class="p">[</span><span class="nx">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">nums</span><span class="p">[</span><span class="nx">i</span><span class="o">++</span><span class="p">];</span>
@@ -3954,12 +3954,12 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.dart</span><pre><span></span><code><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="kt">void</span><span class="w"> </span><span class="n">merge</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="n">List</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">List</span><span class="p">.</span><span class="n">filled</span><span class="p">(</span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="m">0</span><span class="p">);</span>
<a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="m">0</span><span class="p">;</span>
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">])</span>
<a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="w"> </span><span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="o">++</span><span class="p">];</span>
@@ -3995,13 +3995,13 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.rs</span><pre><span></span><code><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="k">fn</span> <span class="nf">merge</span><span class="p">(</span><span class="n">nums</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">i32</span><span class="p">],</span><span class="w"> </span><span class="n">left</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">mid</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">right</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">tmp_size</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="mi">0</span><span class="p">;</span><span class="w"> </span><span class="n">tmp_size</span><span class="p">];</span>
<a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">j</span><span class="p">,</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">k</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">);</span>
<a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">]</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a><span class="w"> </span><span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">];</span>
@@ -4045,13 +4045,13 @@
<div class="tabbed-block">
<div class="highlight"><span class="filename">merge_sort.c</span><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="cm">/* 合并左子数组和右子数组 */</span>
<a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="kt">void</span><span class="w"> </span><span class="nf">merge</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="c1">// 左子数组区间 [left, mid], 右子数组区间 [mid+1, right]</span>
<a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span><span class="c1">// 创建一个临时数组 tmp ,用于存放合并后的结果</span>
<a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">tmpSize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">right</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="o">*</span><span class="p">)</span><span class="n">malloc</span><span class="p">(</span><span class="n">tmpSize</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="k">sizeof</span><span class="p">(</span><span class="kt">int</span><span class="p">));</span>
<a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="w"> </span><span class="c1">// 初始化左子数组和右子数组的起始索引</span>
<a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span>
<a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a><span class="w"> </span><span class="c1">// 当左右子数组都还有元素时,进行比较并将较小的元素复制到临时数组中</span>
<a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">mid</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="n">j</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">j</span><span class="p">])</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-10-12" name="__codelineno-10-12" href="#__codelineno-10-12"></a><span class="w"> </span><span class="n">tmp</span><span class="p">[</span><span class="n">k</span><span class="o">++</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="o">++</span><span class="p">];</span>
@@ -4144,8 +4144,8 @@
</div>
<h2 id="1162">11.6.2 &nbsp; 算法特性<a class="headerlink" href="#1162" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、非自适应排序</strong>:划分产生高度为 <span class="arithmatex">\(\log n\)</span> 的递归树,每层合并的总操作数量为 <span class="arithmatex">\(n\)</span> ,因此总体时间复杂度为 <span class="arithmatex">\(O(n \log n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n)\)</span>、非原地排序</strong>:递归深度为 <span class="arithmatex">\(\log n\)</span> ,使用 <span class="arithmatex">\(O(\log n)\)</span> 大小的栈帧空间。合并操作需要借助辅助数组实现,使用 <span class="arithmatex">\(O(n)\)</span> 大小的额外空间。</li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、非自适应排序</strong>:划分产生高度为 <span class="arithmatex">\(\log n\)</span> 的递归树,每层合并的总操作数量为 <span class="arithmatex">\(n\)</span> ,因此总体时间复杂度为 <span class="arithmatex">\(O(n \log n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n)\)</span>、非原地排序</strong>:递归深度为 <span class="arithmatex">\(\log n\)</span> ,使用 <span class="arithmatex">\(O(\log n)\)</span> 大小的栈帧空间。合并操作需要借助辅助数组实现,使用 <span class="arithmatex">\(O(n)\)</span> 大小的额外空间。</li>
<li><strong>稳定排序</strong>:在合并过程中,相等元素的次序保持不变。</li>
</ul>
<h2 id="1163">11.6.3 &nbsp; 链表排序<a class="headerlink" href="#1163" title="Permanent link">&para;</a></h2>
+15 -15
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -4113,8 +4113,8 @@
</div>
<h2 id="1152">11.5.2 &nbsp; 算法特性<a class="headerlink" href="#1152" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、自适应排序</strong>:在平均情况下,哨兵划分的递归层数为 <span class="arithmatex">\(\log n\)</span> ,每层中的总循环数为 <span class="arithmatex">\(n\)</span> ,总体使用 <span class="arithmatex">\(O(n \log n)\)</span> 时间。在最差情况下,每轮哨兵划分操作都将长度为 <span class="arithmatex">\(n\)</span> 的数组划分为长度为 <span class="arithmatex">\(0\)</span><span class="arithmatex">\(n - 1\)</span> 的两个子数组,此时递归层数达到 <span class="arithmatex">\(n\)</span> ,每层中的循环数为 <span class="arithmatex">\(n\)</span> ,总体使用 <span class="arithmatex">\(O(n^2)\)</span> 时间。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n)\)</span>、原地排序</strong>:在输入数组完全倒序的情况下,达到最差递归深度 <span class="arithmatex">\(n\)</span> ,使用 <span class="arithmatex">\(O(n)\)</span> 栈帧空间。排序操作是在原数组上进行的,未借助额外数组。</li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(n \log n)\)</span>、自适应排序</strong>:在平均情况下,哨兵划分的递归层数为 <span class="arithmatex">\(\log n\)</span> ,每层中的总循环数为 <span class="arithmatex">\(n\)</span> ,总体使用 <span class="arithmatex">\(O(n \log n)\)</span> 时间。在最差情况下,每轮哨兵划分操作都将长度为 <span class="arithmatex">\(n\)</span> 的数组划分为长度为 <span class="arithmatex">\(0\)</span><span class="arithmatex">\(n - 1\)</span> 的两个子数组,此时递归层数达到 <span class="arithmatex">\(n\)</span> ,每层中的循环数为 <span class="arithmatex">\(n\)</span> ,总体使用 <span class="arithmatex">\(O(n^2)\)</span> 时间。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n)\)</span>、原地排序</strong>:在输入数组完全倒序的情况下,达到最差递归深度 <span class="arithmatex">\(n\)</span> ,使用 <span class="arithmatex">\(O(n)\)</span> 栈帧空间。排序操作是在原数组上进行的,未借助额外数组。</li>
<li><strong>非稳定排序</strong>:在哨兵划分的最后一步,基准数可能会被交换至相等元素的右侧。</li>
</ul>
<h2 id="1153">11.5.3 &nbsp; 快速排序为什么快<a class="headerlink" href="#1153" title="Permanent link">&para;</a></h2>
@@ -4134,7 +4134,7 @@
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.py</span><pre><span></span><code><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a><span class="k">def</span> <span class="nf">median_three</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">nums</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">],</span> <span class="n">left</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">mid</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">right</span><span class="p">:</span> <span class="nb">int</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;选取三个元素的中位数&quot;&quot;&quot;</span>
<a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;选取三个候选元素的中位数&quot;&quot;&quot;</span>
<a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a> <span class="c1"># 此处使用异或运算来简化代码</span>
<a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a> <span class="c1"># 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
<a id="__codelineno-24-5" name="__codelineno-24-5" href="#__codelineno-24-5"></a> <span class="k">if</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">nums</span><span class="p">[</span><span class="n">mid</span><span class="p">])</span> <span class="o">^</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">left</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">nums</span><span class="p">[</span><span class="n">right</span><span class="p">]):</span>
@@ -4164,7 +4164,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.cpp</span><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.cpp</span><pre><span></span><code><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">medianThree</span><span class="p">(</span><span class="n">vector</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="o">&amp;</span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4197,7 +4197,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.java</span><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.java</span><pre><span></span><code><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">medianThree</span><span class="p">(</span><span class="kt">int</span><span class="o">[]</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4230,7 +4230,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.cs</span><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.cs</span><pre><span></span><code><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a><span class="kt">int</span><span class="w"> </span><span class="nf">MedianThree</span><span class="p">(</span><span class="kt">int</span><span class="p">[]</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4263,7 +4263,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.go</span><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.go</span><pre><span></span><code><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">q</span><span class="w"> </span><span class="o">*</span><span class="nx">quickSortMedian</span><span class="p">)</span><span class="w"> </span><span class="nx">medianThree</span><span class="p">(</span><span class="nx">nums</span><span class="w"> </span><span class="p">[]</span><span class="kt">int</span><span class="p">,</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="w"> </span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-28-3" name="__codelineno-28-3" href="#__codelineno-28-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码(!= 在这里起到异或的作用)</span>
<a id="__codelineno-28-4" name="__codelineno-28-4" href="#__codelineno-28-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4300,7 +4300,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.swift</span><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.swift</span><pre><span></span><code><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a><span class="kd">func</span> <span class="nf">medianThree</span><span class="p">(</span><span class="n">nums</span><span class="p">:</span> <span class="p">[</span><span class="nb">Int</span><span class="p">],</span> <span class="kr">left</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="n">mid</span><span class="p">:</span> <span class="nb">Int</span><span class="p">,</span> <span class="kr">right</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a> <span class="k">if</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="kr">left</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">nums</span><span class="p">[</span><span class="n">mid</span><span class="p">])</span> <span class="o">!=</span> <span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="kr">left</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">nums</span><span class="p">[</span><span class="kr">right</span><span class="p">])</span> <span class="p">{</span>
<a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a> <span class="k">return</span> <span class="kr">left</span>
@@ -4322,7 +4322,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.js</span><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.js</span><pre><span></span><code><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a><span class="nx">medianThree</span><span class="p">(</span><span class="nx">nums</span><span class="p">,</span><span class="w"> </span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">mid</span><span class="p">,</span><span class="w"> </span><span class="nx">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4357,7 +4357,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.ts</span><pre><span></span><code><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.ts</span><pre><span></span><code><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a><span class="nx">medianThree</span><span class="p">(</span>
<a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a><span class="w"> </span><span class="nx">nums</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">[],</span>
<a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a><span class="w"> </span><span class="nx">left</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">,</span>
@@ -4406,7 +4406,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.dart</span><pre><span></span><code><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.dart</span><pre><span></span><code><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a><span class="kt">int</span><span class="w"> </span><span class="n">_medianThree</span><span class="p">(</span><span class="n">List</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="w"> </span><span class="n">nums</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4437,7 +4437,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.rs</span><pre><span></span><code><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="cm">/* 选取三个元素的中位数 */</span>
<div class="highlight"><span class="filename">quick_sort.rs</span><pre><span></span><code><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="cm">/* 选取三个候选元素的中位数 */</span>
<a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a><span class="k">fn</span> <span class="nf">median_three</span><span class="p">(</span><span class="n">nums</span>: <span class="kp">&amp;</span><span class="nc">mut</span><span class="w"> </span><span class="p">[</span><span class="kt">i32</span><span class="p">],</span><span class="w"> </span><span class="n">left</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">mid</span>: <span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">right</span>: <span class="kt">usize</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">usize</span> <span class="p">{</span>
<a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4473,7 +4473,7 @@
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.c</span><pre><span></span><code><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="cm">/* 快速排序类(中位基准数优化) */</span>
<a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="c1">// 选取三个元素的中位数</span>
<a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="c1">// 选取三个候选元素的中位数</span>
<a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="kt">int</span><span class="w"> </span><span class="nf">medianThree</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">nums</span><span class="p">[],</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">mid</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">right</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
@@ -4506,7 +4506,7 @@
</code></pre></div>
</div>
<div class="tabbed-block">
<div class="highlight"><span class="filename">quick_sort.zig</span><pre><span></span><code><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="c1">// 选取三个元素的中位数</span>
<div class="highlight"><span class="filename">quick_sort.zig</span><pre><span></span><code><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a><span class="c1">// 选取三个候选元素的中位数</span>
<a id="__codelineno-35-2" name="__codelineno-35-2" href="#__codelineno-35-2"></a><span class="k">fn</span><span class="w"> </span><span class="n">medianThree</span><span class="p">(</span><span class="n">nums</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kt">i32</span><span class="p">,</span><span class="w"> </span><span class="n">left</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">mid</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">,</span><span class="w"> </span><span class="n">right</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="p">)</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-35-3" name="__codelineno-35-3" href="#__codelineno-35-3"></a><span class="w"> </span><span class="c1">// 此处使用异或运算来简化代码</span>
<a id="__codelineno-35-4" name="__codelineno-35-4" href="#__codelineno-35-4"></a><span class="w"> </span><span class="c1">// 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1</span>
+4 -4
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3531,7 +3531,7 @@
<div class="arithmatex">\[
x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
\]</div>
<p>其中 <span class="arithmatex">\(\lfloor a \rfloor\)</span> 表示对浮点数 <span class="arithmatex">\(a\)</span> 向下取整,而 <span class="arithmatex">\(\bmod \: d\)</span> 表示对 <span class="arithmatex">\(d\)</span>。对于学号数据,<span class="arithmatex">\(d = 10\)</span><span class="arithmatex">\(k \in [1, 8]\)</span></p>
<p>其中 <span class="arithmatex">\(\lfloor a \rfloor\)</span> 表示对浮点数 <span class="arithmatex">\(a\)</span> 向下取整,而 <span class="arithmatex">\(\bmod \: d\)</span> 表示对 <span class="arithmatex">\(d\)</span>模(取余)。对于学号数据,<span class="arithmatex">\(d = 10\)</span><span class="arithmatex">\(k \in [1, 8]\)</span></p>
<p>此外,我们需要小幅改动计数排序代码,使之可以根据数字的第 <span class="arithmatex">\(k\)</span> 位进行排序:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
<div class="tabbed-content">
@@ -4174,8 +4174,8 @@ x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
<h2 id="11102">11.10.2 &nbsp; 算法特性<a class="headerlink" href="#11102" title="Permanent link">&para;</a></h2>
<p>相较于计数排序,基数排序适用于数值范围较大的情况,<strong>但前提是数据必须可以表示为固定位数的格式,且位数不能过大</strong>。例如,浮点数不适合使用基数排序,因为其位数 <span class="arithmatex">\(k\)</span> 过大,可能导致时间复杂度 <span class="arithmatex">\(O(nk) \gg O(n^2)\)</span></p>
<ul>
<li><strong>时间复杂度 <span class="arithmatex">\(O(nk)\)</span></strong>:设数据量为 <span class="arithmatex">\(n\)</span>、数据为 <span class="arithmatex">\(d\)</span> 进制、最大位数为 <span class="arithmatex">\(k\)</span> ,则对某一位执行计数排序使用 <span class="arithmatex">\(O(n + d)\)</span> 时间,排序所有 <span class="arithmatex">\(k\)</span> 位使用 <span class="arithmatex">\(O((n + d)k)\)</span> 时间。通常情况下,<span class="arithmatex">\(d\)</span><span class="arithmatex">\(k\)</span> 都相对较小,时间复杂度趋向 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + d)\)</span>、非原地排序</strong>:与计数排序相同,基数排序需要借助长度为 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(d\)</span> 的数组 <code>res</code><code>counter</code></li>
<li><strong>时间复杂度 <span class="arithmatex">\(O(nk)\)</span></strong>:设数据量为 <span class="arithmatex">\(n\)</span>、数据为 <span class="arithmatex">\(d\)</span> 进制、最大位数为 <span class="arithmatex">\(k\)</span> ,则对某一位执行计数排序使用 <span class="arithmatex">\(O(n + d)\)</span> 时间,排序所有 <span class="arithmatex">\(k\)</span> 位使用 <span class="arithmatex">\(O((n + d)k)\)</span> 时间。通常情况下,<span class="arithmatex">\(d\)</span><span class="arithmatex">\(k\)</span> 都相对较小,时间复杂度趋向 <span class="arithmatex">\(O(n)\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(n + d)\)</span>、非原地排序</strong>:与计数排序相同,基数排序需要借助长度为 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(d\)</span> 的数组 <code>res</code><code>counter</code></li>
<li><strong>稳定排序</strong>:当计数排序稳定时,基数排序也稳定;当计数排序不稳定时,基数排序无法保证得到正确的排序结果。</li>
</ul>
+2 -2
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3762,7 +3762,7 @@
<h2 id="1121">11.2.1 &nbsp; 算法特性<a class="headerlink" href="#1121" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>时间复杂度为 <span class="arithmatex">\(O(n^2)\)</span>、非自适应排序</strong>:外循环共 <span class="arithmatex">\(n - 1\)</span> 轮,第一轮的未排序区间长度为 <span class="arithmatex">\(n\)</span> ,最后一轮的未排序区间长度为 <span class="arithmatex">\(2\)</span> ,即各轮外循环分别包含 <span class="arithmatex">\(n\)</span><span class="arithmatex">\(n - 1\)</span><span class="arithmatex">\(\dots\)</span><span class="arithmatex">\(3\)</span><span class="arithmatex">\(2\)</span> 轮内循环,求和为 <span class="arithmatex">\(\frac{(n - 1)(n + 2)}{2}\)</span></li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小的额外空间。</li>
<li><strong>空间复杂度 <span class="arithmatex">\(O(1)\)</span>、原地排序</strong>:指针 <span class="arithmatex">\(i\)</span><span class="arithmatex">\(j\)</span> 使用常数大小的额外空间。</li>
<li><strong>非稳定排序</strong>:如图 11-3 所示,元素 <code>nums[i]</code> 有可能被交换至与其相等的元素的右边,导致两者的相对顺序发生改变。</li>
</ul>
<p><a class="glightbox" href="../selection_sort.assets/selection_sort_instability.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="选择排序非稳定示例" class="animation-figure" src="../selection_sort.assets/selection_sort_instability.png" /></a></p>
+1 -1
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+2 -3
View File
@@ -1719,7 +1719,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3533,8 +3533,7 @@
<h3 id="2-q-a">2. &nbsp; Q &amp; A<a class="headerlink" href="#2-q-a" title="Permanent link">&para;</a></h3>
<div class="admonition question">
<p class="admonition-title">排序算法稳定性在什么情况下是必需的?</p>
<p>在现实中,我们有可能基于对象的某个属性进行排序。例如,学生有姓名和身高两个属性,我们希望实现一个多级排序:</p>
<p>先按照姓名进行排序,得到 <code>(A, 180) (B, 185) (C, 170) (D, 170)</code> ;再对身高进行排序。由于排序算法不稳定,因此可能得到 <code>(D, 170) (C, 170) (A, 180) (B, 185)</code></p>
<p>在现实中,我们有可能基于对象的某个属性进行排序。例如,学生有姓名和身高两个属性,我们希望实现一个多级排序:先按照姓名进行排序,得到 <code>(A, 180) (B, 185) (C, 170) (D, 170)</code> ;再对身高进行排序。由于排序算法不稳定,因此可能得到 <code>(D, 170) (C, 170) (A, 180) (B, 185)</code></p>
<p>可以发现,学生 D 和 C 的位置发生了交换,姓名的有序性被破坏了,而这是我们不希望看到的。</p>
</div>
<div class="admonition question">
+29 -29
View File
@@ -1812,7 +1812,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3600,32 +3600,32 @@
</thead>
<tbody>
<tr>
<td>pushFirst()</td>
<td><code>pushFirst()</code></td>
<td>将元素添加至队首</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>pushLast()</td>
<td><code>pushLast()</code></td>
<td>将元素添加至队尾</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>popFirst()</td>
<td><code>popFirst()</code></td>
<td>删除队首元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>popLast()</td>
<td><code>popLast()</code></td>
<td>删除队尾元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>peekFirst()</td>
<td><code>peekFirst()</code></td>
<td>访问队首元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>peekLast()</td>
<td><code>peekLast()</code></td>
<td>访问队尾元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
@@ -5620,7 +5620,7 @@
<a id="__codelineno-24-32" name="__codelineno-24-32" href="#__codelineno-24-32"></a> <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;双向队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-24-33" name="__codelineno-24-33" href="#__codelineno-24-33"></a> <span class="k">return</span>
<a id="__codelineno-24-34" name="__codelineno-24-34" href="#__codelineno-24-34"></a> <span class="c1"># 队首指针向左移动一位</span>
<a id="__codelineno-24-35" name="__codelineno-24-35" href="#__codelineno-24-35"></a> <span class="c1"># 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-24-35" name="__codelineno-24-35" href="#__codelineno-24-35"></a> <span class="c1"># 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-24-36" name="__codelineno-24-36" href="#__codelineno-24-36"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-24-37" name="__codelineno-24-37" href="#__codelineno-24-37"></a> <span class="c1"># 将 num 添加至队首</span>
<a id="__codelineno-24-38" name="__codelineno-24-38" href="#__codelineno-24-38"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_nums</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">_front</span><span class="p">]</span> <span class="o">=</span> <span class="n">num</span>
@@ -5631,7 +5631,7 @@
<a id="__codelineno-24-43" name="__codelineno-24-43" href="#__codelineno-24-43"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span><span class="p">():</span>
<a id="__codelineno-24-44" name="__codelineno-24-44" href="#__codelineno-24-44"></a> <span class="nb">print</span><span class="p">(</span><span class="s2">&quot;双向队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-24-45" name="__codelineno-24-45" href="#__codelineno-24-45"></a> <span class="k">return</span>
<a id="__codelineno-24-46" name="__codelineno-24-46" href="#__codelineno-24-46"></a> <span class="c1"># 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-24-46" name="__codelineno-24-46" href="#__codelineno-24-46"></a> <span class="c1"># 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-24-47" name="__codelineno-24-47" href="#__codelineno-24-47"></a> <span class="n">rear</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span><span class="p">)</span>
<a id="__codelineno-24-48" name="__codelineno-24-48" href="#__codelineno-24-48"></a> <span class="c1"># 将 num 添加至队尾</span>
<a id="__codelineno-24-49" name="__codelineno-24-49" href="#__codelineno-24-49"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span> <span class="o">=</span> <span class="n">num</span>
@@ -5719,7 +5719,7 @@
<a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-25-47" name="__codelineno-25-47" href="#__codelineno-25-47"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-25-48" name="__codelineno-25-48" href="#__codelineno-25-48"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5732,7 +5732,7 @@
<a id="__codelineno-25-55" name="__codelineno-25-55" href="#__codelineno-25-55"></a><span class="w"> </span><span class="n">cout</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="s">&quot;双向队列已满&quot;</span><span class="w"> </span><span class="o">&lt;&lt;</span><span class="w"> </span><span class="n">endl</span><span class="p">;</span>
<a id="__codelineno-25-56" name="__codelineno-25-56" href="#__codelineno-25-56"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-25-57" name="__codelineno-25-57" href="#__codelineno-25-57"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-25-58" name="__codelineno-25-58" href="#__codelineno-25-58"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-25-58" name="__codelineno-25-58" href="#__codelineno-25-58"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-25-59" name="__codelineno-25-59" href="#__codelineno-25-59"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">);</span>
<a id="__codelineno-25-60" name="__codelineno-25-60" href="#__codelineno-25-60"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-25-61" name="__codelineno-25-61" href="#__codelineno-25-61"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5826,7 +5826,7 @@
<a id="__codelineno-26-40" name="__codelineno-26-40" href="#__codelineno-26-40"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-26-41" name="__codelineno-26-41" href="#__codelineno-26-41"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-26-42" name="__codelineno-26-42" href="#__codelineno-26-42"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-26-43" name="__codelineno-26-43" href="#__codelineno-26-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-26-43" name="__codelineno-26-43" href="#__codelineno-26-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-26-44" name="__codelineno-26-44" href="#__codelineno-26-44"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-26-45" name="__codelineno-26-45" href="#__codelineno-26-45"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-26-46" name="__codelineno-26-46" href="#__codelineno-26-46"></a><span class="w"> </span><span class="n">nums</span><span class="o">[</span><span class="n">front</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5839,7 +5839,7 @@
<a id="__codelineno-26-53" name="__codelineno-26-53" href="#__codelineno-26-53"></a><span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">&quot;双向队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-26-54" name="__codelineno-26-54" href="#__codelineno-26-54"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-26-55" name="__codelineno-26-55" href="#__codelineno-26-55"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-26-56" name="__codelineno-26-56" href="#__codelineno-26-56"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-26-56" name="__codelineno-26-56" href="#__codelineno-26-56"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-26-57" name="__codelineno-26-57" href="#__codelineno-26-57"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">);</span>
<a id="__codelineno-26-58" name="__codelineno-26-58" href="#__codelineno-26-58"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-26-59" name="__codelineno-26-59" href="#__codelineno-26-59"></a><span class="w"> </span><span class="n">nums</span><span class="o">[</span><span class="n">rear</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5933,7 +5933,7 @@
<a id="__codelineno-27-40" name="__codelineno-27-40" href="#__codelineno-27-40"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-27-41" name="__codelineno-27-41" href="#__codelineno-27-41"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-27-42" name="__codelineno-27-42" href="#__codelineno-27-42"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-27-43" name="__codelineno-27-43" href="#__codelineno-27-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-27-43" name="__codelineno-27-43" href="#__codelineno-27-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-27-44" name="__codelineno-27-44" href="#__codelineno-27-44"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">);</span>
<a id="__codelineno-27-45" name="__codelineno-27-45" href="#__codelineno-27-45"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-27-46" name="__codelineno-27-46" href="#__codelineno-27-46"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5946,7 +5946,7 @@
<a id="__codelineno-27-53" name="__codelineno-27-53" href="#__codelineno-27-53"></a><span class="w"> </span><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;双向队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-27-54" name="__codelineno-27-54" href="#__codelineno-27-54"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-27-55" name="__codelineno-27-55" href="#__codelineno-27-55"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-27-56" name="__codelineno-27-56" href="#__codelineno-27-56"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-27-56" name="__codelineno-27-56" href="#__codelineno-27-56"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-27-57" name="__codelineno-27-57" href="#__codelineno-27-57"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Index</span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">);</span>
<a id="__codelineno-27-58" name="__codelineno-27-58" href="#__codelineno-27-58"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-27-59" name="__codelineno-27-59" href="#__codelineno-27-59"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -6043,7 +6043,7 @@
<a id="__codelineno-28-41" name="__codelineno-28-41" href="#__codelineno-28-41"></a><span class="w"> </span><span class="k">return</span>
<a id="__codelineno-28-42" name="__codelineno-28-42" href="#__codelineno-28-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-28-43" name="__codelineno-28-43" href="#__codelineno-28-43"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-28-44" name="__codelineno-28-44" href="#__codelineno-28-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-28-44" name="__codelineno-28-44" href="#__codelineno-28-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-28-45" name="__codelineno-28-45" href="#__codelineno-28-45"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-28-46" name="__codelineno-28-46" href="#__codelineno-28-46"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-28-47" name="__codelineno-28-47" href="#__codelineno-28-47"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">num</span>
@@ -6056,7 +6056,7 @@
<a id="__codelineno-28-54" name="__codelineno-28-54" href="#__codelineno-28-54"></a><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="s">&quot;双向队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-28-55" name="__codelineno-28-55" href="#__codelineno-28-55"></a><span class="w"> </span><span class="k">return</span>
<a id="__codelineno-28-56" name="__codelineno-28-56" href="#__codelineno-28-56"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-28-57" name="__codelineno-28-57" href="#__codelineno-28-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-28-57" name="__codelineno-28-57" href="#__codelineno-28-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-28-58" name="__codelineno-28-58" href="#__codelineno-28-58"></a><span class="w"> </span><span class="nx">rear</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queSize</span><span class="p">)</span>
<a id="__codelineno-28-59" name="__codelineno-28-59" href="#__codelineno-28-59"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-28-60" name="__codelineno-28-60" href="#__codelineno-28-60"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">num</span>
@@ -6153,7 +6153,7 @@
<a id="__codelineno-29-41" name="__codelineno-29-41" href="#__codelineno-29-41"></a> <span class="k">return</span>
<a id="__codelineno-29-42" name="__codelineno-29-42" href="#__codelineno-29-42"></a> <span class="p">}</span>
<a id="__codelineno-29-43" name="__codelineno-29-43" href="#__codelineno-29-43"></a> <span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-29-44" name="__codelineno-29-44" href="#__codelineno-29-44"></a> <span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-29-44" name="__codelineno-29-44" href="#__codelineno-29-44"></a> <span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-29-45" name="__codelineno-29-45" href="#__codelineno-29-45"></a> <span class="n">front</span> <span class="p">=</span> <span class="n">index</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="n">front</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<a id="__codelineno-29-46" name="__codelineno-29-46" href="#__codelineno-29-46"></a> <span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-29-47" name="__codelineno-29-47" href="#__codelineno-29-47"></a> <span class="n">nums</span><span class="p">[</span><span class="n">front</span><span class="p">]</span> <span class="p">=</span> <span class="n">num</span>
@@ -6166,7 +6166,7 @@
<a id="__codelineno-29-54" name="__codelineno-29-54" href="#__codelineno-29-54"></a> <span class="bp">print</span><span class="p">(</span><span class="s">&quot;双向队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-29-55" name="__codelineno-29-55" href="#__codelineno-29-55"></a> <span class="k">return</span>
<a id="__codelineno-29-56" name="__codelineno-29-56" href="#__codelineno-29-56"></a> <span class="p">}</span>
<a id="__codelineno-29-57" name="__codelineno-29-57" href="#__codelineno-29-57"></a> <span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-29-57" name="__codelineno-29-57" href="#__codelineno-29-57"></a> <span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-29-58" name="__codelineno-29-58" href="#__codelineno-29-58"></a> <span class="kd">let</span> <span class="nv">rear</span> <span class="p">=</span> <span class="n">index</span><span class="p">(</span><span class="n">i</span><span class="p">:</span> <span class="n">front</span> <span class="o">+</span> <span class="n">size</span><span class="p">())</span>
<a id="__codelineno-29-59" name="__codelineno-29-59" href="#__codelineno-29-59"></a> <span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-29-60" name="__codelineno-29-60" href="#__codelineno-29-60"></a> <span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span> <span class="p">=</span> <span class="n">num</span>
@@ -6263,7 +6263,7 @@
<a id="__codelineno-30-41" name="__codelineno-30-41" href="#__codelineno-30-41"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-30-42" name="__codelineno-30-42" href="#__codelineno-30-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-30-43" name="__codelineno-30-43" href="#__codelineno-30-43"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-30-44" name="__codelineno-30-44" href="#__codelineno-30-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-30-44" name="__codelineno-30-44" href="#__codelineno-30-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-30-45" name="__codelineno-30-45" href="#__codelineno-30-45"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">);</span>
<a id="__codelineno-30-46" name="__codelineno-30-46" href="#__codelineno-30-46"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-30-47" name="__codelineno-30-47" href="#__codelineno-30-47"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">nums</span><span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -6276,7 +6276,7 @@
<a id="__codelineno-30-54" name="__codelineno-30-54" href="#__codelineno-30-54"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;双向队列已满&#39;</span><span class="p">);</span>
<a id="__codelineno-30-55" name="__codelineno-30-55" href="#__codelineno-30-55"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-30-56" name="__codelineno-30-56" href="#__codelineno-30-56"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-30-57" name="__codelineno-30-57" href="#__codelineno-30-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-30-57" name="__codelineno-30-57" href="#__codelineno-30-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-30-58" name="__codelineno-30-58" href="#__codelineno-30-58"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">queSize</span><span class="p">);</span>
<a id="__codelineno-30-59" name="__codelineno-30-59" href="#__codelineno-30-59"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-30-60" name="__codelineno-30-60" href="#__codelineno-30-60"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -6369,7 +6369,7 @@
<a id="__codelineno-31-41" name="__codelineno-31-41" href="#__codelineno-31-41"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-31-42" name="__codelineno-31-42" href="#__codelineno-31-42"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-31-43" name="__codelineno-31-43" href="#__codelineno-31-43"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-31-44" name="__codelineno-31-44" href="#__codelineno-31-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-31-44" name="__codelineno-31-44" href="#__codelineno-31-44"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-31-45" name="__codelineno-31-45" href="#__codelineno-31-45"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mf">1</span><span class="p">);</span>
<a id="__codelineno-31-46" name="__codelineno-31-46" href="#__codelineno-31-46"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-31-47" name="__codelineno-31-47" href="#__codelineno-31-47"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -6382,7 +6382,7 @@
<a id="__codelineno-31-54" name="__codelineno-31-54" href="#__codelineno-31-54"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;双向队列已满&#39;</span><span class="p">);</span>
<a id="__codelineno-31-55" name="__codelineno-31-55" href="#__codelineno-31-55"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-31-56" name="__codelineno-31-56" href="#__codelineno-31-56"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-31-57" name="__codelineno-31-57" href="#__codelineno-31-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-31-57" name="__codelineno-31-57" href="#__codelineno-31-57"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-31-58" name="__codelineno-31-58" href="#__codelineno-31-58"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">rear</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">index</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">queSize</span><span class="p">);</span>
<a id="__codelineno-31-59" name="__codelineno-31-59" href="#__codelineno-31-59"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-31-60" name="__codelineno-31-60" href="#__codelineno-31-60"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -6473,7 +6473,7 @@
<a id="__codelineno-32-39" name="__codelineno-32-39" href="#__codelineno-32-39"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="n">Exception</span><span class="p">(</span><span class="s2">&quot;双向队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-32-40" name="__codelineno-32-40" href="#__codelineno-32-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-32-41" name="__codelineno-32-41" href="#__codelineno-32-41"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-32-42" name="__codelineno-32-42" href="#__codelineno-32-42"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 _front 越过数组头部后回到尾部</span>
<a id="__codelineno-32-42" name="__codelineno-32-42" href="#__codelineno-32-42"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 _front 越过数组头部后回到尾部</span>
<a id="__codelineno-32-43" name="__codelineno-32-43" href="#__codelineno-32-43"></a><span class="w"> </span><span class="n">_front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">_front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="m">1</span><span class="p">);</span>
<a id="__codelineno-32-44" name="__codelineno-32-44" href="#__codelineno-32-44"></a><span class="w"> </span><span class="c1">// 将 _num 添加至队首</span>
<a id="__codelineno-32-45" name="__codelineno-32-45" href="#__codelineno-32-45"></a><span class="w"> </span><span class="n">_nums</span><span class="p">[</span><span class="n">_front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_num</span><span class="p">;</span>
@@ -6485,7 +6485,7 @@
<a id="__codelineno-32-51" name="__codelineno-32-51" href="#__codelineno-32-51"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">_queSize</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">capacity</span><span class="p">())</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-32-52" name="__codelineno-32-52" href="#__codelineno-32-52"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="n">Exception</span><span class="p">(</span><span class="s2">&quot;双向队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-32-53" name="__codelineno-32-53" href="#__codelineno-32-53"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-32-54" name="__codelineno-32-54" href="#__codelineno-32-54"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-32-54" name="__codelineno-32-54" href="#__codelineno-32-54"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-32-55" name="__codelineno-32-55" href="#__codelineno-32-55"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">index</span><span class="p">(</span><span class="n">_front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">_queSize</span><span class="p">);</span>
<a id="__codelineno-32-56" name="__codelineno-32-56" href="#__codelineno-32-56"></a><span class="w"> </span><span class="c1">// 将 _num 添加至队尾</span>
<a id="__codelineno-32-57" name="__codelineno-32-57" href="#__codelineno-32-57"></a><span class="w"> </span><span class="n">_nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_num</span><span class="p">;</span>
@@ -6586,7 +6586,7 @@
<a id="__codelineno-33-45" name="__codelineno-33-45" href="#__codelineno-33-45"></a><span class="w"> </span><span class="k">return</span>
<a id="__codelineno-33-46" name="__codelineno-33-46" href="#__codelineno-33-46"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-33-47" name="__codelineno-33-47" href="#__codelineno-33-47"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-33-48" name="__codelineno-33-48" href="#__codelineno-33-48"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-33-48" name="__codelineno-33-48" href="#__codelineno-33-48"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部后回到尾部</span>
<a id="__codelineno-33-49" name="__codelineno-33-49" href="#__codelineno-33-49"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-33-50" name="__codelineno-33-50" href="#__codelineno-33-50"></a><span class="w"> </span><span class="c1">// 将 num 添加至队首</span>
<a id="__codelineno-33-51" name="__codelineno-33-51" href="#__codelineno-33-51"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">nums</span><span class="p">[</span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -6599,7 +6599,7 @@
<a id="__codelineno-33-58" name="__codelineno-33-58" href="#__codelineno-33-58"></a><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&quot;双向队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-33-59" name="__codelineno-33-59" href="#__codelineno-33-59"></a><span class="w"> </span><span class="k">return</span>
<a id="__codelineno-33-60" name="__codelineno-33-60" href="#__codelineno-33-60"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-33-61" name="__codelineno-33-61" href="#__codelineno-33-61"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-33-61" name="__codelineno-33-61" href="#__codelineno-33-61"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-33-62" name="__codelineno-33-62" href="#__codelineno-33-62"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">index</span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">que_size</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">i32</span><span class="p">);</span>
<a id="__codelineno-33-63" name="__codelineno-33-63" href="#__codelineno-33-63"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-33-64" name="__codelineno-33-64" href="#__codelineno-33-64"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -6705,7 +6705,7 @@
<a id="__codelineno-34-52" name="__codelineno-34-52" href="#__codelineno-34-52"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-34-53" name="__codelineno-34-53" href="#__codelineno-34-53"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-34-54" name="__codelineno-34-54" href="#__codelineno-34-54"></a><span class="w"> </span><span class="c1">// 队首指针向左移动一位</span>
<a id="__codelineno-34-55" name="__codelineno-34-55" href="#__codelineno-34-55"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部回到尾部</span>
<a id="__codelineno-34-55" name="__codelineno-34-55" href="#__codelineno-34-55"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 front 越过数组头部回到尾部</span>
<a id="__codelineno-34-56" name="__codelineno-34-56" href="#__codelineno-34-56"></a><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dequeIndex</span><span class="p">(</span><span class="n">deque</span><span class="p">,</span><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span>
<a id="__codelineno-34-57" name="__codelineno-34-57" href="#__codelineno-34-57"></a><span class="w"> </span><span class="c1">// 将 num 添加到队首</span>
<a id="__codelineno-34-58" name="__codelineno-34-58" href="#__codelineno-34-58"></a><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">nums</span><span class="p">[</span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">front</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -6718,7 +6718,7 @@
<a id="__codelineno-34-65" name="__codelineno-34-65" href="#__codelineno-34-65"></a><span class="w"> </span><span class="n">printf</span><span class="p">(</span><span class="s">&quot;双向队列已满</span><span class="se">\r\n</span><span class="s">&quot;</span><span class="p">);</span>
<a id="__codelineno-34-66" name="__codelineno-34-66" href="#__codelineno-34-66"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-34-67" name="__codelineno-34-67" href="#__codelineno-34-67"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-34-68" name="__codelineno-34-68" href="#__codelineno-34-68"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-34-68" name="__codelineno-34-68" href="#__codelineno-34-68"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-34-69" name="__codelineno-34-69" href="#__codelineno-34-69"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">dequeIndex</span><span class="p">(</span><span class="n">deque</span><span class="p">,</span><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">queSize</span><span class="p">);</span>
<a id="__codelineno-34-70" name="__codelineno-34-70" href="#__codelineno-34-70"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-34-71" name="__codelineno-34-71" href="#__codelineno-34-71"></a><span class="w"> </span><span class="n">deque</span><span class="o">-&gt;</span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
+1 -1
View File
@@ -1721,7 +1721,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
+50 -50
View File
@@ -1812,7 +1812,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3601,17 +3601,17 @@
</thead>
<tbody>
<tr>
<td>push()</td>
<td><code>push()</code></td>
<td>元素入队,即将元素添加至队尾</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>pop()</td>
<td><code>pop()</code></td>
<td>队首元素出队</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>peek()</td>
<td><code>peek()</code></td>
<td>访问队首元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
@@ -3888,7 +3888,7 @@
</div>
</div>
<h2 id="522">5.2.2 &nbsp; 队列实现<a class="headerlink" href="#522" title="Permanent link">&para;</a></h2>
<p>为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素链表和数组都符合要求。</p>
<p>为了实现队列,我们需要一种数据结构,可以在一端添加元素,并在另一端删除元素链表和数组都符合要求。</p>
<h3 id="1">1. &nbsp; 基于链表的实现<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
<p>如图 5-5 所示,我们可以将链表的“头节点”和“尾节点”分别视为“队首”和“队尾”,规定队尾仅可添加节点,队首仅可删除节点。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:3"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1">LinkedListQueue</label><label for="__tabbed_2_2">push()</label><label for="__tabbed_2_3">pop()</label></div>
@@ -3929,7 +3929,7 @@
<a id="__codelineno-12-17" name="__codelineno-12-17" href="#__codelineno-12-17"></a>
<a id="__codelineno-12-18" name="__codelineno-12-18" href="#__codelineno-12-18"></a> <span class="k">def</span> <span class="nf">push</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">num</span><span class="p">:</span> <span class="nb">int</span><span class="p">):</span>
<a id="__codelineno-12-19" name="__codelineno-12-19" href="#__codelineno-12-19"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;入队&quot;&quot;&quot;</span>
<a id="__codelineno-12-20" name="__codelineno-12-20" href="#__codelineno-12-20"></a> <span class="c1"># 尾节点后添加 num</span>
<a id="__codelineno-12-20" name="__codelineno-12-20" href="#__codelineno-12-20"></a> <span class="c1"># 尾节点后添加 num</span>
<a id="__codelineno-12-21" name="__codelineno-12-21" href="#__codelineno-12-21"></a> <span class="n">node</span> <span class="o">=</span> <span class="n">ListNode</span><span class="p">(</span><span class="n">num</span><span class="p">)</span>
<a id="__codelineno-12-22" name="__codelineno-12-22" href="#__codelineno-12-22"></a> <span class="c1"># 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-12-23" name="__codelineno-12-23" href="#__codelineno-12-23"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
@@ -3996,7 +3996,7 @@
<a id="__codelineno-13-28" name="__codelineno-13-28" href="#__codelineno-13-28"></a>
<a id="__codelineno-13-29" name="__codelineno-13-29" href="#__codelineno-13-29"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-13-30" name="__codelineno-13-30" href="#__codelineno-13-30"></a><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">push</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-13-31" name="__codelineno-13-31" href="#__codelineno-13-31"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-13-31" name="__codelineno-13-31" href="#__codelineno-13-31"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-13-32" name="__codelineno-13-32" href="#__codelineno-13-32"></a><span class="w"> </span><span class="n">ListNode</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ListNode</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<a id="__codelineno-13-33" name="__codelineno-13-33" href="#__codelineno-13-33"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-13-34" name="__codelineno-13-34" href="#__codelineno-13-34"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">nullptr</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4066,7 +4066,7 @@
<a id="__codelineno-14-20" name="__codelineno-14-20" href="#__codelineno-14-20"></a>
<a id="__codelineno-14-21" name="__codelineno-14-21" href="#__codelineno-14-21"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-14-22" name="__codelineno-14-22" href="#__codelineno-14-22"></a><span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="nf">push</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-14-23" name="__codelineno-14-23" href="#__codelineno-14-23"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-14-23" name="__codelineno-14-23" href="#__codelineno-14-23"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-14-24" name="__codelineno-14-24" href="#__codelineno-14-24"></a><span class="w"> </span><span class="n">ListNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">ListNode</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<a id="__codelineno-14-25" name="__codelineno-14-25" href="#__codelineno-14-25"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-14-26" name="__codelineno-14-26" href="#__codelineno-14-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4132,7 +4132,7 @@
<a id="__codelineno-15-20" name="__codelineno-15-20" href="#__codelineno-15-20"></a>
<a id="__codelineno-15-21" name="__codelineno-15-21" href="#__codelineno-15-21"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-15-22" name="__codelineno-15-22" href="#__codelineno-15-22"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="k">void</span><span class="w"> </span><span class="nf">Push</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-15-23" name="__codelineno-15-23" href="#__codelineno-15-23"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-15-23" name="__codelineno-15-23" href="#__codelineno-15-23"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-15-24" name="__codelineno-15-24" href="#__codelineno-15-24"></a><span class="w"> </span><span class="n">ListNode</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">new</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<a id="__codelineno-15-25" name="__codelineno-15-25" href="#__codelineno-15-25"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-15-26" name="__codelineno-15-26" href="#__codelineno-15-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4253,7 +4253,7 @@
<a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a>
<a id="__codelineno-17-19" name="__codelineno-17-19" href="#__codelineno-17-19"></a> <span class="cm">/* 入队 */</span>
<a id="__codelineno-17-20" name="__codelineno-17-20" href="#__codelineno-17-20"></a> <span class="kd">func</span> <span class="nf">push</span><span class="p">(</span><span class="n">num</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-17-21" name="__codelineno-17-21" href="#__codelineno-17-21"></a> <span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-17-21" name="__codelineno-17-21" href="#__codelineno-17-21"></a> <span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-17-22" name="__codelineno-17-22" href="#__codelineno-17-22"></a> <span class="kd">let</span> <span class="nv">node</span> <span class="p">=</span> <span class="n">ListNode</span><span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="n">num</span><span class="p">)</span>
<a id="__codelineno-17-23" name="__codelineno-17-23" href="#__codelineno-17-23"></a> <span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-17-24" name="__codelineno-17-24" href="#__codelineno-17-24"></a> <span class="k">if</span> <span class="n">front</span> <span class="p">==</span> <span class="kc">nil</span> <span class="p">{</span>
@@ -4323,7 +4323,7 @@
<a id="__codelineno-18-21" name="__codelineno-18-21" href="#__codelineno-18-21"></a>
<a id="__codelineno-18-22" name="__codelineno-18-22" href="#__codelineno-18-22"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-18-23" name="__codelineno-18-23" href="#__codelineno-18-23"></a><span class="w"> </span><span class="nx">push</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-18-24" name="__codelineno-18-24" href="#__codelineno-18-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-18-24" name="__codelineno-18-24" href="#__codelineno-18-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-18-25" name="__codelineno-18-25" href="#__codelineno-18-25"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">ListNode</span><span class="p">(</span><span class="nx">num</span><span class="p">);</span>
<a id="__codelineno-18-26" name="__codelineno-18-26" href="#__codelineno-18-26"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-18-27" name="__codelineno-18-27" href="#__codelineno-18-27"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4389,7 +4389,7 @@
<a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a>
<a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a><span class="w"> </span><span class="nx">push</span><span class="p">(</span><span class="nx">num</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="ow">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">ListNode</span><span class="p">(</span><span class="nx">num</span><span class="p">);</span>
<a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4456,7 +4456,7 @@
<a id="__codelineno-20-21" name="__codelineno-20-21" href="#__codelineno-20-21"></a>
<a id="__codelineno-20-22" name="__codelineno-20-22" href="#__codelineno-20-22"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-20-23" name="__codelineno-20-23" href="#__codelineno-20-23"></a><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="n">push</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">_num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-20-24" name="__codelineno-20-24" href="#__codelineno-20-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 _num</span>
<a id="__codelineno-20-24" name="__codelineno-20-24" href="#__codelineno-20-24"></a><span class="w"> </span><span class="c1">// 尾节点后添加 _num</span>
<a id="__codelineno-20-25" name="__codelineno-20-25" href="#__codelineno-20-25"></a><span class="w"> </span><span class="kd">final</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ListNode</span><span class="p">(</span><span class="n">_num</span><span class="p">);</span>
<a id="__codelineno-20-26" name="__codelineno-20-26" href="#__codelineno-20-26"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
<a id="__codelineno-20-27" name="__codelineno-20-27" href="#__codelineno-20-27"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">_front</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -4530,7 +4530,7 @@
<a id="__codelineno-21-27" name="__codelineno-21-27" href="#__codelineno-21-27"></a>
<a id="__codelineno-21-28" name="__codelineno-21-28" href="#__codelineno-21-28"></a><span class="w"> </span><span class="cm">/* 入队 */</span>
<a id="__codelineno-21-29" name="__codelineno-21-29" href="#__codelineno-21-29"></a><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">push</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">num</span>: <span class="nc">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-21-30" name="__codelineno-21-30" href="#__codelineno-21-30"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-21-30" name="__codelineno-21-30" href="#__codelineno-21-30"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-21-31" name="__codelineno-21-31" href="#__codelineno-21-31"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">new_rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">ListNode</span>::<span class="n">new</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<a id="__codelineno-21-32" name="__codelineno-21-32" href="#__codelineno-21-32"></a><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">rear</span><span class="p">.</span><span class="n">take</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-21-33" name="__codelineno-21-33" href="#__codelineno-21-33"></a><span class="w"> </span><span class="c1">// 如果队列不为空,则将该节点添加到尾节点后</span>
@@ -4713,7 +4713,7 @@
<a id="__codelineno-23-44" name="__codelineno-23-44" href="#__codelineno-23-44"></a>
<a id="__codelineno-23-45" name="__codelineno-23-45" href="#__codelineno-23-45"></a><span class="w"> </span><span class="c1">// 入队</span>
<a id="__codelineno-23-46" name="__codelineno-23-46" href="#__codelineno-23-46"></a><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">push</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">,</span><span class="w"> </span><span class="n">num</span><span class="o">:</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-23-47" name="__codelineno-23-47" href="#__codelineno-23-47"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-23-47" name="__codelineno-23-47" href="#__codelineno-23-47"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-23-48" name="__codelineno-23-48" href="#__codelineno-23-48"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mem_allocator</span><span class="p">.</span><span class="n">create</span><span class="p">(</span><span class="n">inc</span><span class="p">.</span><span class="n">ListNode</span><span class="p">(</span><span class="n">T</span><span class="p">));</span>
<a id="__codelineno-23-49" name="__codelineno-23-49" href="#__codelineno-23-49"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="n">num</span><span class="p">);</span>
<a id="__codelineno-23-50" name="__codelineno-23-50" href="#__codelineno-23-50"></a><span class="w"> </span><span class="c1">// 如果队列为空,则令头、尾节点都指向该节点</span>
@@ -4809,8 +4809,8 @@
<a id="__codelineno-24-23" name="__codelineno-24-23" href="#__codelineno-24-23"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;入队&quot;&quot;&quot;</span>
<a id="__codelineno-24-24" name="__codelineno-24-24" href="#__codelineno-24-24"></a> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="o">==</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span><span class="p">():</span>
<a id="__codelineno-24-25" name="__codelineno-24-25" href="#__codelineno-24-25"></a> <span class="k">raise</span> <span class="ne">IndexError</span><span class="p">(</span><span class="s2">&quot;队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-24-26" name="__codelineno-24-26" href="#__codelineno-24-26"></a> <span class="c1"># 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-24-27" name="__codelineno-24-27" href="#__codelineno-24-27"></a> <span class="c1"># 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-24-26" name="__codelineno-24-26" href="#__codelineno-24-26"></a> <span class="c1"># 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-24-27" name="__codelineno-24-27" href="#__codelineno-24-27"></a> <span class="c1"># 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-24-28" name="__codelineno-24-28" href="#__codelineno-24-28"></a> <span class="n">rear</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span><span class="p">)</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span><span class="p">()</span>
<a id="__codelineno-24-29" name="__codelineno-24-29" href="#__codelineno-24-29"></a> <span class="c1"># 将 num 添加至队尾</span>
<a id="__codelineno-24-30" name="__codelineno-24-30" href="#__codelineno-24-30"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span> <span class="o">=</span> <span class="n">num</span>
@@ -4819,7 +4819,7 @@
<a id="__codelineno-24-33" name="__codelineno-24-33" href="#__codelineno-24-33"></a> <span class="k">def</span> <span class="nf">pop</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-&gt;</span> <span class="nb">int</span><span class="p">:</span>
<a id="__codelineno-24-34" name="__codelineno-24-34" href="#__codelineno-24-34"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;出队&quot;&quot;&quot;</span>
<a id="__codelineno-24-35" name="__codelineno-24-35" href="#__codelineno-24-35"></a> <span class="n">num</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">peek</span><span class="p">()</span>
<a id="__codelineno-24-36" name="__codelineno-24-36" href="#__codelineno-24-36"></a> <span class="c1"># 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-24-36" name="__codelineno-24-36" href="#__codelineno-24-36"></a> <span class="c1"># 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-24-37" name="__codelineno-24-37" href="#__codelineno-24-37"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">=</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_front</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">capacity</span><span class="p">()</span>
<a id="__codelineno-24-38" name="__codelineno-24-38" href="#__codelineno-24-38"></a> <span class="bp">self</span><span class="o">.</span><span class="n">_size</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-24-39" name="__codelineno-24-39" href="#__codelineno-24-39"></a> <span class="k">return</span> <span class="n">num</span>
@@ -4883,7 +4883,7 @@
<a id="__codelineno-25-40" name="__codelineno-25-40" href="#__codelineno-25-40"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-25-41" name="__codelineno-25-41" href="#__codelineno-25-41"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-25-42" name="__codelineno-25-42" href="#__codelineno-25-42"></a><span class="w"> </span><span class="c1">// 计算队尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-25-43" name="__codelineno-25-43" href="#__codelineno-25-43"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-25-44" name="__codelineno-25-44" href="#__codelineno-25-44"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">queCapacity</span><span class="p">;</span>
<a id="__codelineno-25-45" name="__codelineno-25-45" href="#__codelineno-25-45"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-25-46" name="__codelineno-25-46" href="#__codelineno-25-46"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -4893,7 +4893,7 @@
<a id="__codelineno-25-50" name="__codelineno-25-50" href="#__codelineno-25-50"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-25-51" name="__codelineno-25-51" href="#__codelineno-25-51"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">pop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-25-52" name="__codelineno-25-52" href="#__codelineno-25-52"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">peek</span><span class="p">();</span>
<a id="__codelineno-25-53" name="__codelineno-25-53" href="#__codelineno-25-53"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-25-53" name="__codelineno-25-53" href="#__codelineno-25-53"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-25-54" name="__codelineno-25-54" href="#__codelineno-25-54"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">queCapacity</span><span class="p">;</span>
<a id="__codelineno-25-55" name="__codelineno-25-55" href="#__codelineno-25-55"></a><span class="w"> </span><span class="n">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-25-56" name="__codelineno-25-56" href="#__codelineno-25-56"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -4951,8 +4951,8 @@
<a id="__codelineno-26-30" name="__codelineno-26-30" href="#__codelineno-26-30"></a><span class="w"> </span><span class="n">System</span><span class="p">.</span><span class="na">out</span><span class="p">.</span><span class="na">println</span><span class="p">(</span><span class="s">&quot;队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-26-31" name="__codelineno-26-31" href="#__codelineno-26-31"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-26-32" name="__codelineno-26-32" href="#__codelineno-26-32"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-26-33" name="__codelineno-26-33" href="#__codelineno-26-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-26-34" name="__codelineno-26-34" href="#__codelineno-26-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-26-33" name="__codelineno-26-33" href="#__codelineno-26-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-26-34" name="__codelineno-26-34" href="#__codelineno-26-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-26-35" name="__codelineno-26-35" href="#__codelineno-26-35"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capacity</span><span class="p">();</span>
<a id="__codelineno-26-36" name="__codelineno-26-36" href="#__codelineno-26-36"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-26-37" name="__codelineno-26-37" href="#__codelineno-26-37"></a><span class="w"> </span><span class="n">nums</span><span class="o">[</span><span class="n">rear</span><span class="o">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -4962,7 +4962,7 @@
<a id="__codelineno-26-41" name="__codelineno-26-41" href="#__codelineno-26-41"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-26-42" name="__codelineno-26-42" href="#__codelineno-26-42"></a><span class="w"> </span><span class="kd">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">pop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-26-43" name="__codelineno-26-43" href="#__codelineno-26-43"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">peek</span><span class="p">();</span>
<a id="__codelineno-26-44" name="__codelineno-26-44" href="#__codelineno-26-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-26-44" name="__codelineno-26-44" href="#__codelineno-26-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-26-45" name="__codelineno-26-45" href="#__codelineno-26-45"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capacity</span><span class="p">();</span>
<a id="__codelineno-26-46" name="__codelineno-26-46" href="#__codelineno-26-46"></a><span class="w"> </span><span class="n">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-26-47" name="__codelineno-26-47" href="#__codelineno-26-47"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5020,8 +5020,8 @@
<a id="__codelineno-27-30" name="__codelineno-27-30" href="#__codelineno-27-30"></a><span class="w"> </span><span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&quot;队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-27-31" name="__codelineno-27-31" href="#__codelineno-27-31"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-27-32" name="__codelineno-27-32" href="#__codelineno-27-32"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-27-33" name="__codelineno-27-33" href="#__codelineno-27-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-27-34" name="__codelineno-27-34" href="#__codelineno-27-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-27-33" name="__codelineno-27-33" href="#__codelineno-27-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-27-34" name="__codelineno-27-34" href="#__codelineno-27-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-27-35" name="__codelineno-27-35" href="#__codelineno-27-35"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">Capacity</span><span class="p">();</span>
<a id="__codelineno-27-36" name="__codelineno-27-36" href="#__codelineno-27-36"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-27-37" name="__codelineno-27-37" href="#__codelineno-27-37"></a><span class="w"> </span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5031,7 +5031,7 @@
<a id="__codelineno-27-41" name="__codelineno-27-41" href="#__codelineno-27-41"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-27-42" name="__codelineno-27-42" href="#__codelineno-27-42"></a><span class="w"> </span><span class="k">public</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="nf">Pop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-27-43" name="__codelineno-27-43" href="#__codelineno-27-43"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Peek</span><span class="p">();</span>
<a id="__codelineno-27-44" name="__codelineno-27-44" href="#__codelineno-27-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-27-44" name="__codelineno-27-44" href="#__codelineno-27-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-27-45" name="__codelineno-27-45" href="#__codelineno-27-45"></a><span class="w"> </span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">Capacity</span><span class="p">();</span>
<a id="__codelineno-27-46" name="__codelineno-27-46" href="#__codelineno-27-46"></a><span class="w"> </span><span class="n">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-27-47" name="__codelineno-27-47" href="#__codelineno-27-47"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5091,8 +5091,8 @@
<a id="__codelineno-28-32" name="__codelineno-28-32" href="#__codelineno-28-32"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queSize</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queCapacity</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-28-33" name="__codelineno-28-33" href="#__codelineno-28-33"></a><span class="w"> </span><span class="k">return</span>
<a id="__codelineno-28-34" name="__codelineno-28-34" href="#__codelineno-28-34"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-28-35" name="__codelineno-28-35" href="#__codelineno-28-35"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-28-36" name="__codelineno-28-36" href="#__codelineno-28-36"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-28-35" name="__codelineno-28-35" href="#__codelineno-28-35"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-28-36" name="__codelineno-28-36" href="#__codelineno-28-36"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-28-37" name="__codelineno-28-37" href="#__codelineno-28-37"></a><span class="w"> </span><span class="nx">rear</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="p">(</span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queCapacity</span>
<a id="__codelineno-28-38" name="__codelineno-28-38" href="#__codelineno-28-38"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-28-39" name="__codelineno-28-39" href="#__codelineno-28-39"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">num</span>
@@ -5102,7 +5102,7 @@
<a id="__codelineno-28-43" name="__codelineno-28-43" href="#__codelineno-28-43"></a><span class="cm">/* 出队 */</span>
<a id="__codelineno-28-44" name="__codelineno-28-44" href="#__codelineno-28-44"></a><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">q</span><span class="w"> </span><span class="o">*</span><span class="nx">arrayQueue</span><span class="p">)</span><span class="w"> </span><span class="nx">pop</span><span class="p">()</span><span class="w"> </span><span class="kt">any</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-28-45" name="__codelineno-28-45" href="#__codelineno-28-45"></a><span class="w"> </span><span class="nx">num</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">peek</span><span class="p">()</span>
<a id="__codelineno-28-46" name="__codelineno-28-46" href="#__codelineno-28-46"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-28-46" name="__codelineno-28-46" href="#__codelineno-28-46"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-28-47" name="__codelineno-28-47" href="#__codelineno-28-47"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="p">(</span><span class="nx">q</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queCapacity</span>
<a id="__codelineno-28-48" name="__codelineno-28-48" href="#__codelineno-28-48"></a><span class="w"> </span><span class="nx">q</span><span class="p">.</span><span class="nx">queSize</span><span class="o">--</span>
<a id="__codelineno-28-49" name="__codelineno-28-49" href="#__codelineno-28-49"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span>
@@ -5160,8 +5160,8 @@
<a id="__codelineno-29-30" name="__codelineno-29-30" href="#__codelineno-29-30"></a> <span class="bp">print</span><span class="p">(</span><span class="s">&quot;队列已满&quot;</span><span class="p">)</span>
<a id="__codelineno-29-31" name="__codelineno-29-31" href="#__codelineno-29-31"></a> <span class="k">return</span>
<a id="__codelineno-29-32" name="__codelineno-29-32" href="#__codelineno-29-32"></a> <span class="p">}</span>
<a id="__codelineno-29-33" name="__codelineno-29-33" href="#__codelineno-29-33"></a> <span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-29-34" name="__codelineno-29-34" href="#__codelineno-29-34"></a> <span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-29-33" name="__codelineno-29-33" href="#__codelineno-29-33"></a> <span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-29-34" name="__codelineno-29-34" href="#__codelineno-29-34"></a> <span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-29-35" name="__codelineno-29-35" href="#__codelineno-29-35"></a> <span class="kd">let</span> <span class="nv">rear</span> <span class="p">=</span> <span class="p">(</span><span class="n">front</span> <span class="o">+</span> <span class="n">queSize</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span><span class="p">()</span>
<a id="__codelineno-29-36" name="__codelineno-29-36" href="#__codelineno-29-36"></a> <span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-29-37" name="__codelineno-29-37" href="#__codelineno-29-37"></a> <span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span> <span class="p">=</span> <span class="n">num</span>
@@ -5172,7 +5172,7 @@
<a id="__codelineno-29-42" name="__codelineno-29-42" href="#__codelineno-29-42"></a> <span class="p">@</span><span class="n">discardableResult</span>
<a id="__codelineno-29-43" name="__codelineno-29-43" href="#__codelineno-29-43"></a> <span class="kd">func</span> <span class="nf">pop</span><span class="p">()</span> <span class="p">-&gt;</span> <span class="nb">Int</span> <span class="p">{</span>
<a id="__codelineno-29-44" name="__codelineno-29-44" href="#__codelineno-29-44"></a> <span class="kd">let</span> <span class="nv">num</span> <span class="p">=</span> <span class="n">peek</span><span class="p">()</span>
<a id="__codelineno-29-45" name="__codelineno-29-45" href="#__codelineno-29-45"></a> <span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-29-45" name="__codelineno-29-45" href="#__codelineno-29-45"></a> <span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-29-46" name="__codelineno-29-46" href="#__codelineno-29-46"></a> <span class="n">front</span> <span class="p">=</span> <span class="p">(</span><span class="n">front</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">%</span> <span class="n">capacity</span><span class="p">()</span>
<a id="__codelineno-29-47" name="__codelineno-29-47" href="#__codelineno-29-47"></a> <span class="n">queSize</span> <span class="o">-=</span> <span class="mi">1</span>
<a id="__codelineno-29-48" name="__codelineno-29-48" href="#__codelineno-29-48"></a> <span class="k">return</span> <span class="n">num</span>
@@ -5230,8 +5230,8 @@
<a id="__codelineno-30-29" name="__codelineno-30-29" href="#__codelineno-30-29"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;队列已满&#39;</span><span class="p">);</span>
<a id="__codelineno-30-30" name="__codelineno-30-30" href="#__codelineno-30-30"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-30-31" name="__codelineno-30-31" href="#__codelineno-30-31"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-30-32" name="__codelineno-30-32" href="#__codelineno-30-32"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-30-33" name="__codelineno-30-33" href="#__codelineno-30-33"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-30-32" name="__codelineno-30-32" href="#__codelineno-30-32"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-30-33" name="__codelineno-30-33" href="#__codelineno-30-33"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-30-34" name="__codelineno-30-34" href="#__codelineno-30-34"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">size</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-30-35" name="__codelineno-30-35" href="#__codelineno-30-35"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-30-36" name="__codelineno-30-36" href="#__codelineno-30-36"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -5241,7 +5241,7 @@
<a id="__codelineno-30-40" name="__codelineno-30-40" href="#__codelineno-30-40"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-30-41" name="__codelineno-30-41" href="#__codelineno-30-41"></a><span class="w"> </span><span class="nx">pop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-30-42" name="__codelineno-30-42" href="#__codelineno-30-42"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">peek</span><span class="p">();</span>
<a id="__codelineno-30-43" name="__codelineno-30-43" href="#__codelineno-30-43"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-30-43" name="__codelineno-30-43" href="#__codelineno-30-43"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-30-44" name="__codelineno-30-44" href="#__codelineno-30-44"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-30-45" name="__codelineno-30-45" href="#__codelineno-30-45"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-30-46" name="__codelineno-30-46" href="#__codelineno-30-46"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -5298,8 +5298,8 @@
<a id="__codelineno-31-30" name="__codelineno-31-30" href="#__codelineno-31-30"></a><span class="w"> </span><span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;队列已满&#39;</span><span class="p">);</span>
<a id="__codelineno-31-31" name="__codelineno-31-31" href="#__codelineno-31-31"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-31-32" name="__codelineno-31-32" href="#__codelineno-31-32"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-31-33" name="__codelineno-31-33" href="#__codelineno-31-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-31-34" name="__codelineno-31-34" href="#__codelineno-31-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-31-33" name="__codelineno-31-33" href="#__codelineno-31-33"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-31-34" name="__codelineno-31-34" href="#__codelineno-31-34"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-31-35" name="__codelineno-31-35" href="#__codelineno-31-35"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-31-36" name="__codelineno-31-36" href="#__codelineno-31-36"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-31-37" name="__codelineno-31-37" href="#__codelineno-31-37"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">nums</span><span class="p">[</span><span class="nx">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -5309,7 +5309,7 @@
<a id="__codelineno-31-41" name="__codelineno-31-41" href="#__codelineno-31-41"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-31-42" name="__codelineno-31-42" href="#__codelineno-31-42"></a><span class="w"> </span><span class="nx">pop</span><span class="p">()</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-31-43" name="__codelineno-31-43" href="#__codelineno-31-43"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">peek</span><span class="p">();</span>
<a id="__codelineno-31-44" name="__codelineno-31-44" href="#__codelineno-31-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-31-44" name="__codelineno-31-44" href="#__codelineno-31-44"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-31-45" name="__codelineno-31-45" href="#__codelineno-31-45"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">capacity</span><span class="p">;</span>
<a id="__codelineno-31-46" name="__codelineno-31-46" href="#__codelineno-31-46"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-31-47" name="__codelineno-31-47" href="#__codelineno-31-47"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">num</span><span class="p">;</span>
@@ -5365,8 +5365,8 @@
<a id="__codelineno-32-29" name="__codelineno-32-29" href="#__codelineno-32-29"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">_queSize</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">capaCity</span><span class="p">())</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-32-30" name="__codelineno-32-30" href="#__codelineno-32-30"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="n">Exception</span><span class="p">(</span><span class="s2">&quot;队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-32-31" name="__codelineno-32-31" href="#__codelineno-32-31"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-32-32" name="__codelineno-32-32" href="#__codelineno-32-32"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-32-33" name="__codelineno-32-33" href="#__codelineno-32-33"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-32-32" name="__codelineno-32-32" href="#__codelineno-32-32"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-32-33" name="__codelineno-32-33" href="#__codelineno-32-33"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-32-34" name="__codelineno-32-34" href="#__codelineno-32-34"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">_front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">_queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capaCity</span><span class="p">();</span>
<a id="__codelineno-32-35" name="__codelineno-32-35" href="#__codelineno-32-35"></a><span class="w"> </span><span class="c1">// 将 _num 添加至队尾</span>
<a id="__codelineno-32-36" name="__codelineno-32-36" href="#__codelineno-32-36"></a><span class="w"> </span><span class="n">_nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">_num</span><span class="p">;</span>
@@ -5376,7 +5376,7 @@
<a id="__codelineno-32-40" name="__codelineno-32-40" href="#__codelineno-32-40"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-32-41" name="__codelineno-32-41" href="#__codelineno-32-41"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">pop</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-32-42" name="__codelineno-32-42" href="#__codelineno-32-42"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">_num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">peek</span><span class="p">();</span>
<a id="__codelineno-32-43" name="__codelineno-32-43" href="#__codelineno-32-43"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-32-43" name="__codelineno-32-43" href="#__codelineno-32-43"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-32-44" name="__codelineno-32-44" href="#__codelineno-32-44"></a><span class="w"> </span><span class="n">_front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">_front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="m">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">capaCity</span><span class="p">();</span>
<a id="__codelineno-32-45" name="__codelineno-32-45" href="#__codelineno-32-45"></a><span class="w"> </span><span class="n">_queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-32-46" name="__codelineno-32-46" href="#__codelineno-32-46"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">_num</span><span class="p">;</span>
@@ -5443,8 +5443,8 @@
<a id="__codelineno-33-38" name="__codelineno-33-38" href="#__codelineno-33-38"></a><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">&quot;队列已满&quot;</span><span class="p">);</span>
<a id="__codelineno-33-39" name="__codelineno-33-39" href="#__codelineno-33-39"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-33-40" name="__codelineno-33-40" href="#__codelineno-33-40"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-33-41" name="__codelineno-33-41" href="#__codelineno-33-41"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-33-42" name="__codelineno-33-42" href="#__codelineno-33-42"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-33-41" name="__codelineno-33-41" href="#__codelineno-33-41"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-33-42" name="__codelineno-33-42" href="#__codelineno-33-42"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-33-43" name="__codelineno-33-43" href="#__codelineno-33-43"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">que_size</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">que_capacity</span><span class="p">;</span>
<a id="__codelineno-33-44" name="__codelineno-33-44" href="#__codelineno-33-44"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-33-45" name="__codelineno-33-45" href="#__codelineno-33-45"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="kt">usize</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5454,7 +5454,7 @@
<a id="__codelineno-33-49" name="__codelineno-33-49" href="#__codelineno-33-49"></a><span class="w"> </span><span class="cm">/* 出队 */</span>
<a id="__codelineno-33-50" name="__codelineno-33-50" href="#__codelineno-33-50"></a><span class="w"> </span><span class="k">fn</span> <span class="nf">pop</span><span class="p">(</span><span class="o">&amp;</span><span class="k">mut</span><span class="w"> </span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kt">i32</span> <span class="p">{</span>
<a id="__codelineno-33-51" name="__codelineno-33-51" href="#__codelineno-33-51"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">peek</span><span class="p">();</span>
<a id="__codelineno-33-52" name="__codelineno-33-52" href="#__codelineno-33-52"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-33-52" name="__codelineno-33-52" href="#__codelineno-33-52"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-33-53" name="__codelineno-33-53" href="#__codelineno-33-53"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">que_capacity</span><span class="p">;</span>
<a id="__codelineno-33-54" name="__codelineno-33-54" href="#__codelineno-33-54"></a><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">que_size</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-33-55" name="__codelineno-33-55" href="#__codelineno-33-55"></a><span class="w"> </span><span class="n">num</span>
@@ -5535,7 +5535,7 @@
<a id="__codelineno-34-50" name="__codelineno-34-50" href="#__codelineno-34-50"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-34-51" name="__codelineno-34-51" href="#__codelineno-34-51"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-34-52" name="__codelineno-34-52" href="#__codelineno-34-52"></a><span class="w"> </span><span class="c1">// 计算队尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-34-53" name="__codelineno-34-53" href="#__codelineno-34-53"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-34-53" name="__codelineno-34-53" href="#__codelineno-34-53"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-34-54" name="__codelineno-34-54" href="#__codelineno-34-54"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">queCapacity</span><span class="p">;</span>
<a id="__codelineno-34-55" name="__codelineno-34-55" href="#__codelineno-34-55"></a><span class="w"> </span><span class="c1">// 将 num 添加至队尾</span>
<a id="__codelineno-34-56" name="__codelineno-34-56" href="#__codelineno-34-56"></a><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5545,7 +5545,7 @@
<a id="__codelineno-34-60" name="__codelineno-34-60" href="#__codelineno-34-60"></a><span class="cm">/* 出队 */</span>
<a id="__codelineno-34-61" name="__codelineno-34-61" href="#__codelineno-34-61"></a><span class="kt">int</span><span class="w"> </span><span class="nf">pop</span><span class="p">(</span><span class="n">ArrayQueue</span><span class="w"> </span><span class="o">*</span><span class="n">queue</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-34-62" name="__codelineno-34-62" href="#__codelineno-34-62"></a><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">peek</span><span class="p">(</span><span class="n">queue</span><span class="p">);</span>
<a id="__codelineno-34-63" name="__codelineno-34-63" href="#__codelineno-34-63"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-34-63" name="__codelineno-34-63" href="#__codelineno-34-63"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-34-64" name="__codelineno-34-64" href="#__codelineno-34-64"></a><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">queCapacity</span><span class="p">;</span>
<a id="__codelineno-34-65" name="__codelineno-34-65" href="#__codelineno-34-65"></a><span class="w"> </span><span class="n">queue</span><span class="o">-&gt;</span><span class="n">queSize</span><span class="o">--</span><span class="p">;</span>
<a id="__codelineno-34-66" name="__codelineno-34-66" href="#__codelineno-34-66"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
@@ -5603,10 +5603,10 @@
<a id="__codelineno-35-48" name="__codelineno-35-48" href="#__codelineno-35-48"></a><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">&quot;队列已满</span><span class="se">\n</span><span class="s">&quot;</span><span class="p">,</span><span class="w"> </span><span class="p">.{});</span>
<a id="__codelineno-35-49" name="__codelineno-35-49" href="#__codelineno-35-49"></a><span class="w"> </span><span class="k">return</span><span class="p">;</span>
<a id="__codelineno-35-50" name="__codelineno-35-50" href="#__codelineno-35-50"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-35-51" name="__codelineno-35-51" href="#__codelineno-35-51"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-35-52" name="__codelineno-35-52" href="#__codelineno-35-52"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-35-51" name="__codelineno-35-51" href="#__codelineno-35-51"></a><span class="w"> </span><span class="c1">// 计算尾指针,指向队尾索引 + 1</span>
<a id="__codelineno-35-52" name="__codelineno-35-52" href="#__codelineno-35-52"></a><span class="w"> </span><span class="c1">// 通过取余操作实现 rear 越过数组尾部后回到头部</span>
<a id="__codelineno-35-53" name="__codelineno-35-53" href="#__codelineno-35-53"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">rear</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">queSize</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">capacity</span><span class="p">();</span>
<a id="__codelineno-35-54" name="__codelineno-35-54" href="#__codelineno-35-54"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-35-54" name="__codelineno-35-54" href="#__codelineno-35-54"></a><span class="w"> </span><span class="c1">// 尾节点后添加 num</span>
<a id="__codelineno-35-55" name="__codelineno-35-55" href="#__codelineno-35-55"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">nums</span><span class="p">[</span><span class="n">rear</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
<a id="__codelineno-35-56" name="__codelineno-35-56" href="#__codelineno-35-56"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">queSize</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-35-57" name="__codelineno-35-57" href="#__codelineno-35-57"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span>
@@ -5614,7 +5614,7 @@
<a id="__codelineno-35-59" name="__codelineno-35-59" href="#__codelineno-35-59"></a><span class="w"> </span><span class="c1">// 出队</span>
<a id="__codelineno-35-60" name="__codelineno-35-60" href="#__codelineno-35-60"></a><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">pop</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">)</span><span class="w"> </span><span class="n">T</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-35-61" name="__codelineno-35-61" href="#__codelineno-35-61"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">num</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">peek</span><span class="p">();</span>
<a id="__codelineno-35-62" name="__codelineno-35-62" href="#__codelineno-35-62"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-35-62" name="__codelineno-35-62" href="#__codelineno-35-62"></a><span class="w"> </span><span class="c1">// 队首指针向后移动一位,若越过尾部则返回到数组头部</span>
<a id="__codelineno-35-63" name="__codelineno-35-63" href="#__codelineno-35-63"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">front</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">%</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">capacity</span><span class="p">();</span>
<a id="__codelineno-35-64" name="__codelineno-35-64" href="#__codelineno-35-64"></a><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">queSize</span><span class="w"> </span><span class="o">-=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
<a id="__codelineno-35-65" name="__codelineno-35-65" href="#__codelineno-35-65"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">num</span><span class="p">;</span>
+9 -9
View File
@@ -1215,7 +1215,7 @@
<li class="md-nav__item">
<a href="#511" class="md-nav__link">
<span class="md-ellipsis">
5.1.1 &nbsp; 栈常用操作
5.1.1 &nbsp;常用操作
</span>
</a>
@@ -1821,7 +1821,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3505,7 +3505,7 @@
<li class="md-nav__item">
<a href="#511" class="md-nav__link">
<span class="md-ellipsis">
5.1.1 &nbsp; 栈常用操作
5.1.1 &nbsp;常用操作
</span>
</a>
@@ -3599,13 +3599,13 @@
<!-- Page content -->
<h1 id="51">5.1 &nbsp;<a class="headerlink" href="#51" title="Permanent link">&para;</a></h1>
<p>「栈 stack」是一种遵循先入后出逻辑的线性数据结构。</p>
<p>「栈 stack」是一种遵循先入后出逻辑的线性数据结构。</p>
<p>我们可以将栈类比为桌面上的一摞盘子,如果想取出底部的盘子,则需要先将上面的盘子依次移走。我们将盘子替换为各种类型的元素(如整数、字符、对象等),就得到了栈这种数据结构。</p>
<p>如图 5-1 所示,我们把堆叠元素的顶部称为“栈顶”,底部称为“栈底”。将把元素添加到栈顶的操作叫作“入栈”,删除栈顶元素的操作叫作“出栈”。</p>
<p><a class="glightbox" href="../stack.assets/stack_operations.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="栈的先入后出规则" class="animation-figure" src="../stack.assets/stack_operations.png" /></a></p>
<p align="center"> 图 5-1 &nbsp; 栈的先入后出规则 </p>
<h2 id="511">5.1.1 &nbsp; 栈常用操作<a class="headerlink" href="#511" title="Permanent link">&para;</a></h2>
<h2 id="511">5.1.1 &nbsp;常用操作<a class="headerlink" href="#511" title="Permanent link">&para;</a></h2>
<p>栈的常用操作如表 5-1 所示,具体的方法名需要根据所使用的编程语言来确定。在此,我们以常见的 <code>push()</code><code>pop()</code><code>peek()</code> 命名为例。</p>
<p align="center"> 表 5-1 &nbsp; 栈的操作效率 </p>
@@ -3620,17 +3620,17 @@
</thead>
<tbody>
<tr>
<td>push()</td>
<td><code>push()</code></td>
<td>元素入栈(添加至栈顶)</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>pop()</td>
<td><code>pop()</code></td>
<td>栈顶元素出栈</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
<tr>
<td>peek()</td>
<td><code>peek()</code></td>
<td>访问栈顶元素</td>
<td><span class="arithmatex">\(O(1)\)</span></td>
</tr>
@@ -3642,7 +3642,7 @@
<div class="tabbed-content">
<div class="tabbed-block">
<div class="highlight"><span class="filename">stack.py</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="c1"># 初始化栈</span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="c1"># Python 没有内置的栈类,可以把 List 当作栈来使用 </span>
<a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="c1"># Python 没有内置的栈类,可以把 list 当作栈来使用 </span>
<a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="n">stack</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>
<a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a><span class="c1"># 元素入栈</span>
+1 -1
View File
@@ -1779,7 +1779,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -1788,7 +1788,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3543,12 +3543,12 @@
<p><strong>映射公式的角色相当于链表中的指针</strong>。给定数组中的任意一个节点,我们都可以通过映射公式来访问它的左(右)子节点。</p>
<h2 id="732">7.3.2 &nbsp; 表示任意二叉树<a class="headerlink" href="#732" title="Permanent link">&para;</a></h2>
<p>完美二叉树是一个特例,在二叉树的中间层通常存在许多 <span class="arithmatex">\(\text{None}\)</span> 。由于层序遍历序列并不包含这些 <span class="arithmatex">\(\text{None}\)</span> ,因此我们无法仅凭该序列来推测 <span class="arithmatex">\(\text{None}\)</span> 的数量和分布位置。<strong>这意味着存在多种二叉树结构都符合该层序遍历序列</strong></p>
<p>完美二叉树是一个特例,在二叉树的中间层通常存在许多 <code>None</code> 。由于层序遍历序列并不包含这些 <code>None</code> ,因此我们无法仅凭该序列来推测 <code>None</code> 的数量和分布位置。<strong>这意味着存在多种二叉树结构都符合该层序遍历序列</strong></p>
<p>如图 7-13 所示,给定一棵非完美二叉树,上述数组表示方法已经失效。</p>
<p><a class="glightbox" href="../array_representation_of_tree.assets/array_representation_without_empty.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="层序遍历序列对应多种二叉树可能性" class="animation-figure" src="../array_representation_of_tree.assets/array_representation_without_empty.png" /></a></p>
<p align="center"> 图 7-13 &nbsp; 层序遍历序列对应多种二叉树可能性 </p>
<p>为了解决此问题,<strong>我们可以考虑在层序遍历序列中显式地写出所有 <span class="arithmatex">\(\text{None}\)</span></strong> 。如图 7-14 所示,这样处理后,层序遍历序列就可以唯一表示二叉树了。示例代码如下:</p>
<p>为了解决此问题,<strong>我们可以考虑在层序遍历序列中显式地写出所有 <code>None</code></strong> 。如图 7-14 所示,这样处理后,层序遍历序列就可以唯一表示二叉树了。示例代码如下:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="1:12"><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" /><input id="__tabbed_1_10" name="__tabbed_1" type="radio" /><input id="__tabbed_1_11" name="__tabbed_1" type="radio" /><input id="__tabbed_1_12" name="__tabbed_1" type="radio" /><div class="tabbed-labels"><label for="__tabbed_1_1">Python</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Java</label><label for="__tabbed_1_4">C#</label><label for="__tabbed_1_5">Go</label><label for="__tabbed_1_6">Swift</label><label for="__tabbed_1_7">JS</label><label for="__tabbed_1_8">TS</label><label for="__tabbed_1_9">Dart</label><label for="__tabbed_1_10">Rust</label><label for="__tabbed_1_11">C</label><label for="__tabbed_1_12">Zig</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -3626,8 +3626,8 @@
<p><a class="glightbox" href="../array_representation_of_tree.assets/array_representation_with_empty.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="任意类型二叉树的数组表示" class="animation-figure" src="../array_representation_of_tree.assets/array_representation_with_empty.png" /></a></p>
<p align="center"> 图 7-14 &nbsp; 任意类型二叉树的数组表示 </p>
<p>值得说明的是,<strong>完全二叉树非常适合使用数组来表示</strong>。回顾完全二叉树的定义,<span class="arithmatex">\(\text{None}\)</span> 只出现在最底层且靠右的位置,<strong>因此所有 <span class="arithmatex">\(\text{None}\)</span> 一定出现在层序遍历序列的末尾</strong></p>
<p>这意味着使用数组表示完全二叉树时,可以省略存储所有 <span class="arithmatex">\(\text{None}\)</span> ,非常方便。图 7-15 给出了一个例子。</p>
<p>值得说明的是,<strong>完全二叉树非常适合使用数组来表示</strong>。回顾完全二叉树的定义,<code>None</code> 只出现在最底层且靠右的位置,<strong>因此所有 <code>None</code> 一定出现在层序遍历序列的末尾</strong></p>
<p>这意味着使用数组表示完全二叉树时,可以省略存储所有 <code>None</code> ,非常方便。图 7-15 给出了一个例子。</p>
<p><a class="glightbox" href="../array_representation_of_tree.assets/array_representation_complete_binary_tree.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="完全二叉树的数组表示" class="animation-figure" src="../array_representation_of_tree.assets/array_representation_complete_binary_tree.png" /></a></p>
<p align="center"> 图 7-15 &nbsp; 完全二叉树的数组表示 </p>
@@ -4645,7 +4645,7 @@
<ul>
<li>数组存储需要连续内存空间,因此不适合存储数据量过大的树。</li>
<li>增删节点需要通过数组插入与删除操作实现,效率较低。</li>
<li>当二叉树中存在大量 <span class="arithmatex">\(\text{None}\)</span> 时,数组中包含的节点数据比重较低,空间利用率较低。</li>
<li>当二叉树中存在大量 <code>None</code> 时,数组中包含的节点数据比重较低,空间利用率较低。</li>
</ul>
<!-- Source file information -->
+35 -35
View File
@@ -1905,7 +1905,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3767,16 +3767,16 @@
<!-- Page content -->
<h1 id="75-avl">7.5 &nbsp; AVL 树 *<a class="headerlink" href="#75-avl" title="Permanent link">&para;</a></h1>
<p>在“二叉搜索树”章节中我们提到,在多次插入和删除操作后,二叉搜索树可能退化为链表。在这种情况下,所有操作的时间复杂度将从 <span class="arithmatex">\(O(\log n)\)</span> 化为 <span class="arithmatex">\(O(n)\)</span></p>
<p>在“二叉搜索树”章节中我们提到,在多次插入和删除操作后,二叉搜索树可能退化为链表。在这种情况下,所有操作的时间复杂度将从 <span class="arithmatex">\(O(\log n)\)</span> 化为 <span class="arithmatex">\(O(n)\)</span></p>
<p>如图 7-24 所示,经过两次删除节点操作,这棵二叉搜索树便会退化为链表。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_degradation_from_removing_node.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="AVL 树在删除节点后发生退化" class="animation-figure" src="../avl_tree.assets/avltree_degradation_from_removing_node.png" /></a></p>
<p align="center"> 图 7-24 &nbsp; AVL 树在删除节点后发生退化 </p>
<p>再例如,在图 7-25 所示的完美二叉树中插入两个节点后,树将严重向左倾斜,查找操作的时间复杂度也随之化。</p>
<p>再例如,在图 7-25 所示的完美二叉树中插入两个节点后,树将严重向左倾斜,查找操作的时间复杂度也随之化。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_degradation_from_inserting_node.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="AVL 树在插入节点后发生退化" class="animation-figure" src="../avl_tree.assets/avltree_degradation_from_inserting_node.png" /></a></p>
<p align="center"> 图 7-25 &nbsp; AVL 树在插入节点后发生退化 </p>
<p>1962 年 G. M. Adelson-Velsky 和 E. M. Landis 在论文 "An algorithm for the organization of information" 中提出了「AVL 树」。论文中详细描述了一系列操作,确保在持续添加和删除节点后,AVL 树不会退化,从而使得各种操作的时间复杂度保持在 <span class="arithmatex">\(O(\log n)\)</span> 级别。换句话说,在需要频繁进行增删查改操作的场景中,AVL 树能始终保持高效的数据操作性能,具有很好的应用价值。</p>
<p>1962 年 G. M. Adelson-Velsky 和 E. M. Landis 在论文An algorithm for the organization of information中提出了「AVL 树」。论文中详细描述了一系列操作,确保在持续添加和删除节点后,AVL 树不会退化,从而使得各种操作的时间复杂度保持在 <span class="arithmatex">\(O(\log n)\)</span> 级别。换句话说,在需要频繁进行增删查改操作的场景中,AVL 树能始终保持高效的数据操作性能,具有很好的应用价值。</p>
<h2 id="751-avl">7.5.1 &nbsp; AVL 树常见术语<a class="headerlink" href="#751-avl" title="Permanent link">&para;</a></h2>
<p>AVL 树既是二叉搜索树也是平衡二叉树,同时满足这两类二叉树的所有性质,因此也被称为「平衡二叉搜索树 balanced binary search tree」。</p>
<h3 id="1">1. &nbsp; 节点高度<a class="headerlink" href="#1" title="Permanent link">&para;</a></h3>
@@ -3947,7 +3947,7 @@
</div>
</div>
</div>
<p>“节点高度”是指从该节点到最远叶节点的距离,即所经过的“边”的数量。需要特别注意的是,叶节点的高度为 <span class="arithmatex">\(0\)</span> ,而空节点的高度为 <span class="arithmatex">\(-1\)</span> 。我们将创建两个工具函数,分别用于获取和更新节点的高度:</p>
<p>“节点高度”是指从该节点到它的最远叶节点的距离,即所经过的“边”的数量。需要特别注意的是,叶节点的高度为 <span class="arithmatex">\(0\)</span> ,而空节点的高度为 <span class="arithmatex">\(-1\)</span> 。我们将创建两个工具函数,分别用于获取和更新节点的高度:</p>
<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">Python</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Java</label><label for="__tabbed_2_4">C#</label><label for="__tabbed_2_5">Go</label><label for="__tabbed_2_6">Swift</label><label for="__tabbed_2_7">JS</label><label for="__tabbed_2_8">TS</label><label for="__tabbed_2_9">Dart</label><label for="__tabbed_2_10">Rust</label><label for="__tabbed_2_11">C</label><label for="__tabbed_2_12">Zig</label></div>
<div class="tabbed-content">
<div class="tabbed-block">
@@ -4311,9 +4311,9 @@
</div>
<p align="center"> 图 7-26 &nbsp; 右旋操作步骤 </p>
<p>如图 7-27 所示,当节点 <code>child</code> 有右子节点(记为 <code>grandChild</code> )时,需要在右旋中添加一步:将 <code>grandChild</code> 作为 <code>node</code> 的左子节点。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_right_rotate_with_grandchild.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="有 grandChild 的右旋操作" class="animation-figure" src="../avl_tree.assets/avltree_right_rotate_with_grandchild.png" /></a></p>
<p align="center"> 图 7-27 &nbsp; 有 grandChild 的右旋操作 </p>
<p>如图 7-27 所示,当节点 <code>child</code> 有右子节点(记为 <code>grand_child</code> )时,需要在右旋中添加一步:将 <code>grand_child</code> 作为 <code>node</code> 的左子节点。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_right_rotate_with_grandchild.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="有 grand_child 的右旋操作" class="animation-figure" src="../avl_tree.assets/avltree_right_rotate_with_grandchild.png" /></a></p>
<p align="center"> 图 7-27 &nbsp; 有 grand_child 的右旋操作 </p>
<p>“向右旋转”是一种形象化的说法,实际上需要通过修改节点指针来实现,代码如下所示:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="5:12"><input checked="checked" id="__tabbed_5_1" name="__tabbed_5" type="radio" /><input id="__tabbed_5_2" name="__tabbed_5" type="radio" /><input id="__tabbed_5_3" name="__tabbed_5" type="radio" /><input id="__tabbed_5_4" name="__tabbed_5" type="radio" /><input id="__tabbed_5_5" name="__tabbed_5" type="radio" /><input id="__tabbed_5_6" name="__tabbed_5" type="radio" /><input id="__tabbed_5_7" name="__tabbed_5" type="radio" /><input id="__tabbed_5_8" name="__tabbed_5" type="radio" /><input id="__tabbed_5_9" name="__tabbed_5" type="radio" /><input id="__tabbed_5_10" name="__tabbed_5" type="radio" /><input id="__tabbed_5_11" name="__tabbed_5" type="radio" /><input id="__tabbed_5_12" name="__tabbed_5" type="radio" /><div class="tabbed-labels"><label for="__tabbed_5_1">Python</label><label for="__tabbed_5_2">C++</label><label for="__tabbed_5_3">Java</label><label for="__tabbed_5_4">C#</label><label for="__tabbed_5_5">Go</label><label for="__tabbed_5_6">Swift</label><label for="__tabbed_5_7">JS</label><label for="__tabbed_5_8">TS</label><label for="__tabbed_5_9">Dart</label><label for="__tabbed_5_10">Rust</label><label for="__tabbed_5_11">C</label><label for="__tabbed_5_12">Zig</label></div>
@@ -4522,9 +4522,9 @@
<p><a class="glightbox" href="../avl_tree.assets/avltree_left_rotate.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="左旋操作" class="animation-figure" src="../avl_tree.assets/avltree_left_rotate.png" /></a></p>
<p align="center"> 图 7-28 &nbsp; 左旋操作 </p>
<p>同理,如图 7-29 所示,当节点 <code>child</code> 有左子节点(记为 <code>grandChild</code> )时,需要在左旋中添加一步:将 <code>grandChild</code> 作为 <code>node</code> 的右子节点。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_left_rotate_with_grandchild.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="有 grandChild 的左旋操作" class="animation-figure" src="../avl_tree.assets/avltree_left_rotate_with_grandchild.png" /></a></p>
<p align="center"> 图 7-29 &nbsp; 有 grandChild 的左旋操作 </p>
<p>同理,如图 7-29 所示,当节点 <code>child</code> 有左子节点(记为 <code>grand_child</code> )时,需要在左旋中添加一步:将 <code>grand_child</code> 作为 <code>node</code> 的右子节点。</p>
<p><a class="glightbox" href="../avl_tree.assets/avltree_left_rotate_with_grandchild.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="有 grand_child 的左旋操作" class="animation-figure" src="../avl_tree.assets/avltree_left_rotate_with_grandchild.png" /></a></p>
<p align="center"> 图 7-29 &nbsp; 有 grand_child 的左旋操作 </p>
<p>可以观察到,<strong>右旋和左旋操作在逻辑上是镜像对称的,它们分别解决的两种失衡情况也是对称的</strong>。基于对称性,我们只需将右旋的实现代码中的所有的 <code>left</code> 替换为 <code>right</code> ,将所有的 <code>right</code> 替换为 <code>left</code> ,即可得到左旋的实现代码:</p>
<div class="tabbed-set tabbed-alternate" data-tabs="6:12"><input checked="checked" id="__tabbed_6_1" name="__tabbed_6" type="radio" /><input id="__tabbed_6_2" name="__tabbed_6" type="radio" /><input id="__tabbed_6_3" name="__tabbed_6" type="radio" /><input id="__tabbed_6_4" name="__tabbed_6" type="radio" /><input id="__tabbed_6_5" name="__tabbed_6" type="radio" /><input id="__tabbed_6_6" name="__tabbed_6" type="radio" /><input id="__tabbed_6_7" name="__tabbed_6" type="radio" /><input id="__tabbed_6_8" name="__tabbed_6" type="radio" /><input id="__tabbed_6_9" name="__tabbed_6" type="radio" /><input id="__tabbed_6_10" name="__tabbed_6" type="radio" /><input id="__tabbed_6_11" name="__tabbed_6" type="radio" /><input id="__tabbed_6_12" name="__tabbed_6" type="radio" /><div class="tabbed-labels"><label for="__tabbed_6_1">Python</label><label for="__tabbed_6_2">C++</label><label for="__tabbed_6_3">Java</label><label for="__tabbed_6_4">C#</label><label for="__tabbed_6_5">Go</label><label for="__tabbed_6_6">Swift</label><label for="__tabbed_6_7">JS</label><label for="__tabbed_6_8">TS</label><label for="__tabbed_6_9">Dart</label><label for="__tabbed_6_10">Rust</label><label for="__tabbed_6_11">C</label><label for="__tabbed_6_12">Zig</label></div>
@@ -5183,7 +5183,7 @@
<a id="__codelineno-72-6" name="__codelineno-72-6" href="#__codelineno-72-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;递归插入节点(辅助方法)&quot;&quot;&quot;</span>
<a id="__codelineno-72-7" name="__codelineno-72-7" href="#__codelineno-72-7"></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-72-8" name="__codelineno-72-8" href="#__codelineno-72-8"></a> <span class="k">return</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-72-9" name="__codelineno-72-9" href="#__codelineno-72-9"></a> <span class="c1"># 1. 查找插入位置并插入节点</span>
<a id="__codelineno-72-9" name="__codelineno-72-9" href="#__codelineno-72-9"></a> <span class="c1"># 1. 查找插入位置并插入节点</span>
<a id="__codelineno-72-10" name="__codelineno-72-10" href="#__codelineno-72-10"></a> <span class="k">if</span> <span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">.</span><span class="n">val</span><span class="p">:</span>
<a id="__codelineno-72-11" name="__codelineno-72-11" href="#__codelineno-72-11"></a> <span class="n">node</span><span class="o">.</span><span class="n">left</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">insert_helper</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-72-12" name="__codelineno-72-12" href="#__codelineno-72-12"></a> <span class="k">elif</span> <span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">.</span><span class="n">val</span><span class="p">:</span>
@@ -5207,7 +5207,7 @@
<a id="__codelineno-73-7" name="__codelineno-73-7" href="#__codelineno-73-7"></a><span class="n">TreeNode</span><span class="w"> </span><span class="o">*</span><span class="nf">insertHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-73-8" name="__codelineno-73-8" href="#__codelineno-73-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">nullptr</span><span class="p">)</span>
<a id="__codelineno-73-9" name="__codelineno-73-9" href="#__codelineno-73-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">TreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-73-10" name="__codelineno-73-10" href="#__codelineno-73-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-73-10" name="__codelineno-73-10" href="#__codelineno-73-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-73-11" name="__codelineno-73-11" href="#__codelineno-73-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-73-12" name="__codelineno-73-12" href="#__codelineno-73-12"></a><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-73-13" name="__codelineno-73-13" href="#__codelineno-73-13"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
@@ -5232,7 +5232,7 @@
<a id="__codelineno-74-7" name="__codelineno-74-7" href="#__codelineno-74-7"></a><span class="n">TreeNode</span><span class="w"> </span><span class="nf">insertHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-74-8" name="__codelineno-74-8" href="#__codelineno-74-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span>
<a id="__codelineno-74-9" name="__codelineno-74-9" href="#__codelineno-74-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">TreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-74-10" name="__codelineno-74-10" href="#__codelineno-74-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-74-10" name="__codelineno-74-10" href="#__codelineno-74-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-74-11" name="__codelineno-74-11" href="#__codelineno-74-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">val</span><span class="p">)</span>
<a id="__codelineno-74-12" name="__codelineno-74-12" href="#__codelineno-74-12"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="na">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-74-13" name="__codelineno-74-13" href="#__codelineno-74-13"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">val</span><span class="p">)</span>
@@ -5256,7 +5256,7 @@
<a id="__codelineno-75-6" name="__codelineno-75-6" href="#__codelineno-75-6"></a><span class="cm">/* 递归插入节点(辅助方法) */</span>
<a id="__codelineno-75-7" name="__codelineno-75-7" href="#__codelineno-75-7"></a><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">InsertHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-75-8" name="__codelineno-75-8" href="#__codelineno-75-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">new</span><span class="w"> </span><span class="n">TreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-75-9" name="__codelineno-75-9" href="#__codelineno-75-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-75-9" name="__codelineno-75-9" href="#__codelineno-75-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-75-10" name="__codelineno-75-10" href="#__codelineno-75-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-75-11" name="__codelineno-75-11" href="#__codelineno-75-11"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">InsertHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-75-12" name="__codelineno-75-12" href="#__codelineno-75-12"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="nf">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
@@ -5282,7 +5282,7 @@
<a id="__codelineno-76-8" name="__codelineno-76-8" href="#__codelineno-76-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-76-9" name="__codelineno-76-9" href="#__codelineno-76-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">NewTreeNode</span><span class="p">(</span><span class="nx">val</span><span class="p">)</span>
<a id="__codelineno-76-10" name="__codelineno-76-10" href="#__codelineno-76-10"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-76-11" name="__codelineno-76-11" href="#__codelineno-76-11"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-76-11" name="__codelineno-76-11" href="#__codelineno-76-11"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-76-12" name="__codelineno-76-12" href="#__codelineno-76-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Val</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-76-13" name="__codelineno-76-13" href="#__codelineno-76-13"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Left</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">Left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">)</span>
<a id="__codelineno-76-14" name="__codelineno-76-14" href="#__codelineno-76-14"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="p">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Val</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5312,7 +5312,7 @@
<a id="__codelineno-77-9" name="__codelineno-77-9" href="#__codelineno-77-9"></a> <span class="k">if</span> <span class="n">node</span> <span class="p">==</span> <span class="kc">nil</span> <span class="p">{</span>
<a id="__codelineno-77-10" name="__codelineno-77-10" href="#__codelineno-77-10"></a> <span class="k">return</span> <span class="n">TreeNode</span><span class="p">(</span><span class="n">x</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-77-11" name="__codelineno-77-11" href="#__codelineno-77-11"></a> <span class="p">}</span>
<a id="__codelineno-77-12" name="__codelineno-77-12" href="#__codelineno-77-12"></a> <span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-77-12" name="__codelineno-77-12" href="#__codelineno-77-12"></a> <span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-77-13" name="__codelineno-77-13" href="#__codelineno-77-13"></a> <span class="k">if</span> <span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="p">!.</span><span class="n">val</span> <span class="p">{</span>
<a id="__codelineno-77-14" name="__codelineno-77-14" href="#__codelineno-77-14"></a> <span class="n">node</span><span class="p">?.</span><span class="kr">left</span> <span class="p">=</span> <span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">node</span><span class="p">?.</span><span class="kr">left</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-77-15" name="__codelineno-77-15" href="#__codelineno-77-15"></a> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="p">!.</span><span class="n">val</span> <span class="p">{</span>
@@ -5337,7 +5337,7 @@
<a id="__codelineno-78-6" name="__codelineno-78-6" href="#__codelineno-78-6"></a><span class="cm">/* 递归插入节点(辅助方法) */</span>
<a id="__codelineno-78-7" name="__codelineno-78-7" href="#__codelineno-78-7"></a><span class="err">#</span><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-78-8" name="__codelineno-78-8" href="#__codelineno-78-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">node</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">TreeNode</span><span class="p">(</span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-78-9" name="__codelineno-78-9" href="#__codelineno-78-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-78-9" name="__codelineno-78-9" href="#__codelineno-78-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-78-10" name="__codelineno-78-10" href="#__codelineno-78-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-78-11" name="__codelineno-78-11" href="#__codelineno-78-11"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span>
<a id="__codelineno-78-12" name="__codelineno-78-12" href="#__codelineno-78-12"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">right</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">right</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
@@ -5359,7 +5359,7 @@
<a id="__codelineno-79-6" name="__codelineno-79-6" href="#__codelineno-79-6"></a><span class="cm">/* 递归插入节点(辅助方法) */</span>
<a id="__codelineno-79-7" name="__codelineno-79-7" href="#__codelineno-79-7"></a><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="o">:</span><span class="w"> </span><span class="kt">TreeNode</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nx">TreeNode</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-79-8" name="__codelineno-79-8" href="#__codelineno-79-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">node</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">TreeNode</span><span class="p">(</span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-79-9" name="__codelineno-79-9" href="#__codelineno-79-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-79-9" name="__codelineno-79-9" href="#__codelineno-79-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-79-10" name="__codelineno-79-10" href="#__codelineno-79-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-79-11" name="__codelineno-79-11" href="#__codelineno-79-11"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">insertHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-79-12" name="__codelineno-79-12" href="#__codelineno-79-12"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5384,7 +5384,7 @@
<a id="__codelineno-80-6" name="__codelineno-80-6" href="#__codelineno-80-6"></a><span class="cm">/* 递归插入节点(辅助方法) */</span>
<a id="__codelineno-80-7" name="__codelineno-80-7" href="#__codelineno-80-7"></a><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">insertHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-80-8" name="__codelineno-80-8" href="#__codelineno-80-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">TreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-80-9" name="__codelineno-80-9" href="#__codelineno-80-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-80-9" name="__codelineno-80-9" href="#__codelineno-80-9"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-80-10" name="__codelineno-80-10" href="#__codelineno-80-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-80-11" name="__codelineno-80-11" href="#__codelineno-80-11"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-80-12" name="__codelineno-80-12" href="#__codelineno-80-12"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
@@ -5409,7 +5409,7 @@
<a id="__codelineno-81-7" name="__codelineno-81-7" href="#__codelineno-81-7"></a><span class="k">fn</span> <span class="nf">insert_helper</span><span class="p">(</span><span class="n">node</span>: <span class="nc">OptionTreeNodeRc</span><span class="p">,</span><span class="w"> </span><span class="n">val</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">OptionTreeNodeRc</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-81-8" name="__codelineno-81-8" href="#__codelineno-81-8"></a><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-81-9" name="__codelineno-81-9" href="#__codelineno-81-9"></a><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">node</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-81-10" name="__codelineno-81-10" href="#__codelineno-81-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-81-10" name="__codelineno-81-10" href="#__codelineno-81-10"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-81-11" name="__codelineno-81-11" href="#__codelineno-81-11"></a><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-81-12" name="__codelineno-81-12" href="#__codelineno-81-12"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">node_val</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">borrow</span><span class="p">().</span><span class="n">val</span><span class="p">;</span>
<a id="__codelineno-81-13" name="__codelineno-81-13" href="#__codelineno-81-13"></a><span class="w"> </span><span class="n">node_val</span>
@@ -5450,7 +5450,7 @@
<a id="__codelineno-82-8" name="__codelineno-82-8" href="#__codelineno-82-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-82-9" name="__codelineno-82-9" href="#__codelineno-82-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">newTreeNode</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-82-10" name="__codelineno-82-10" href="#__codelineno-82-10"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-82-11" name="__codelineno-82-11" href="#__codelineno-82-11"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-82-11" name="__codelineno-82-11" href="#__codelineno-82-11"></a><span class="w"> </span><span class="cm">/* 1. 查找插入位置并插入节点 */</span>
<a id="__codelineno-82-12" name="__codelineno-82-12" href="#__codelineno-82-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-82-13" name="__codelineno-82-13" href="#__codelineno-82-13"></a><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-82-14" name="__codelineno-82-14" href="#__codelineno-82-14"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5482,7 +5482,7 @@
<a id="__codelineno-83-11" name="__codelineno-83-11" href="#__codelineno-83-11"></a><span class="w"> </span><span class="n">tmp_node</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-83-12" name="__codelineno-83-12" href="#__codelineno-83-12"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">tmp_node</span><span class="p">;</span>
<a id="__codelineno-83-13" name="__codelineno-83-13" href="#__codelineno-83-13"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-83-14" name="__codelineno-83-14" href="#__codelineno-83-14"></a><span class="w"> </span><span class="c1">// 1. 查找插入位置并插入节点</span>
<a id="__codelineno-83-14" name="__codelineno-83-14" href="#__codelineno-83-14"></a><span class="w"> </span><span class="c1">// 1. 查找插入位置并插入节点</span>
<a id="__codelineno-83-15" name="__codelineno-83-15" href="#__codelineno-83-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-83-16" name="__codelineno-83-16" href="#__codelineno-83-16"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">insertHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-83-17" name="__codelineno-83-17" href="#__codelineno-83-17"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5513,7 +5513,7 @@
<a id="__codelineno-84-6" name="__codelineno-84-6" href="#__codelineno-84-6"></a><span class="w"> </span><span class="sd">&quot;&quot;&quot;递归删除节点(辅助方法)&quot;&quot;&quot;</span>
<a id="__codelineno-84-7" name="__codelineno-84-7" href="#__codelineno-84-7"></a> <span class="k">if</span> <span class="n">node</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<a id="__codelineno-84-8" name="__codelineno-84-8" href="#__codelineno-84-8"></a> <span class="k">return</span> <span class="kc">None</span>
<a id="__codelineno-84-9" name="__codelineno-84-9" href="#__codelineno-84-9"></a> <span class="c1"># 1. 查找节点并删除</span>
<a id="__codelineno-84-9" name="__codelineno-84-9" href="#__codelineno-84-9"></a> <span class="c1"># 1. 查找节点并删除</span>
<a id="__codelineno-84-10" name="__codelineno-84-10" href="#__codelineno-84-10"></a> <span class="k">if</span> <span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="o">.</span><span class="n">val</span><span class="p">:</span>
<a id="__codelineno-84-11" name="__codelineno-84-11" href="#__codelineno-84-11"></a> <span class="n">node</span><span class="o">.</span><span class="n">left</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">remove_helper</span><span class="p">(</span><span class="n">node</span><span class="o">.</span><span class="n">left</span><span class="p">,</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-84-12" name="__codelineno-84-12" href="#__codelineno-84-12"></a> <span class="k">elif</span> <span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="o">.</span><span class="n">val</span><span class="p">:</span>
@@ -5550,7 +5550,7 @@
<a id="__codelineno-85-7" name="__codelineno-85-7" href="#__codelineno-85-7"></a><span class="n">TreeNode</span><span class="w"> </span><span class="o">*</span><span class="nf">removeHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="w"> </span><span class="o">*</span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-85-8" name="__codelineno-85-8" href="#__codelineno-85-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">nullptr</span><span class="p">)</span>
<a id="__codelineno-85-9" name="__codelineno-85-9" href="#__codelineno-85-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">nullptr</span><span class="p">;</span>
<a id="__codelineno-85-10" name="__codelineno-85-10" href="#__codelineno-85-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-85-10" name="__codelineno-85-10" href="#__codelineno-85-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-85-11" name="__codelineno-85-11" href="#__codelineno-85-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-85-12" name="__codelineno-85-12" href="#__codelineno-85-12"></a><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-85-13" name="__codelineno-85-13" href="#__codelineno-85-13"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span>
@@ -5597,7 +5597,7 @@
<a id="__codelineno-86-7" name="__codelineno-86-7" href="#__codelineno-86-7"></a><span class="n">TreeNode</span><span class="w"> </span><span class="nf">removeHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-86-8" name="__codelineno-86-8" href="#__codelineno-86-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span>
<a id="__codelineno-86-9" name="__codelineno-86-9" href="#__codelineno-86-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-86-10" name="__codelineno-86-10" href="#__codelineno-86-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-86-10" name="__codelineno-86-10" href="#__codelineno-86-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-86-11" name="__codelineno-86-11" href="#__codelineno-86-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">val</span><span class="p">)</span>
<a id="__codelineno-86-12" name="__codelineno-86-12" href="#__codelineno-86-12"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="na">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-86-13" name="__codelineno-86-13" href="#__codelineno-86-13"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="na">val</span><span class="p">)</span>
@@ -5638,7 +5638,7 @@
<a id="__codelineno-87-6" name="__codelineno-87-6" href="#__codelineno-87-6"></a><span class="cm">/* 递归删除节点(辅助方法) */</span>
<a id="__codelineno-87-7" name="__codelineno-87-7" href="#__codelineno-87-7"></a><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">RemoveHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-87-8" name="__codelineno-87-8" href="#__codelineno-87-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">null</span><span class="p">;</span>
<a id="__codelineno-87-9" name="__codelineno-87-9" href="#__codelineno-87-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-87-9" name="__codelineno-87-9" href="#__codelineno-87-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-87-10" name="__codelineno-87-10" href="#__codelineno-87-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-87-11" name="__codelineno-87-11" href="#__codelineno-87-11"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">RemoveHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-87-12" name="__codelineno-87-12" href="#__codelineno-87-12"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="nf">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
@@ -5681,7 +5681,7 @@
<a id="__codelineno-88-8" name="__codelineno-88-8" href="#__codelineno-88-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">nil</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-88-9" name="__codelineno-88-9" href="#__codelineno-88-9"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">nil</span>
<a id="__codelineno-88-10" name="__codelineno-88-10" href="#__codelineno-88-10"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-88-11" name="__codelineno-88-11" href="#__codelineno-88-11"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-88-11" name="__codelineno-88-11" href="#__codelineno-88-11"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-88-12" name="__codelineno-88-12" href="#__codelineno-88-12"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="p">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Val</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-88-13" name="__codelineno-88-13" href="#__codelineno-88-13"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Left</span><span class="w"> </span><span class="p">=</span><span class="w"> </span><span class="nx">t</span><span class="p">.</span><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">Left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">)</span>
<a id="__codelineno-88-14" name="__codelineno-88-14" href="#__codelineno-88-14"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="nx">val</span><span class="w"> </span><span class="p">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">Val</span><span class="p">.(</span><span class="kt">int</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5730,7 +5730,7 @@
<a id="__codelineno-89-9" name="__codelineno-89-9" href="#__codelineno-89-9"></a> <span class="k">if</span> <span class="n">node</span> <span class="p">==</span> <span class="kc">nil</span> <span class="p">{</span>
<a id="__codelineno-89-10" name="__codelineno-89-10" href="#__codelineno-89-10"></a> <span class="k">return</span> <span class="kc">nil</span>
<a id="__codelineno-89-11" name="__codelineno-89-11" href="#__codelineno-89-11"></a> <span class="p">}</span>
<a id="__codelineno-89-12" name="__codelineno-89-12" href="#__codelineno-89-12"></a> <span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-89-12" name="__codelineno-89-12" href="#__codelineno-89-12"></a> <span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-89-13" name="__codelineno-89-13" href="#__codelineno-89-13"></a> <span class="k">if</span> <span class="n">val</span> <span class="o">&lt;</span> <span class="n">node</span><span class="p">!.</span><span class="n">val</span> <span class="p">{</span>
<a id="__codelineno-89-14" name="__codelineno-89-14" href="#__codelineno-89-14"></a> <span class="n">node</span><span class="p">?.</span><span class="kr">left</span> <span class="p">=</span> <span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="p">:</span> <span class="n">node</span><span class="p">?.</span><span class="kr">left</span><span class="p">,</span> <span class="n">val</span><span class="p">:</span> <span class="n">val</span><span class="p">)</span>
<a id="__codelineno-89-15" name="__codelineno-89-15" href="#__codelineno-89-15"></a> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="n">val</span> <span class="o">&gt;</span> <span class="n">node</span><span class="p">!.</span><span class="n">val</span> <span class="p">{</span>
@@ -5773,7 +5773,7 @@
<a id="__codelineno-90-6" name="__codelineno-90-6" href="#__codelineno-90-6"></a><span class="cm">/* 递归删除节点(辅助方法) */</span>
<a id="__codelineno-90-7" name="__codelineno-90-7" href="#__codelineno-90-7"></a><span class="err">#</span><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-90-8" name="__codelineno-90-8" href="#__codelineno-90-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">node</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-90-9" name="__codelineno-90-9" href="#__codelineno-90-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-90-9" name="__codelineno-90-9" href="#__codelineno-90-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-90-10" name="__codelineno-90-10" href="#__codelineno-90-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-90-11" name="__codelineno-90-11" href="#__codelineno-90-11"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span>
<a id="__codelineno-90-12" name="__codelineno-90-12" href="#__codelineno-90-12"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">right</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="err">#</span><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">right</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
@@ -5811,7 +5811,7 @@
<a id="__codelineno-91-6" name="__codelineno-91-6" href="#__codelineno-91-6"></a><span class="cm">/* 递归删除节点(辅助方法) */</span>
<a id="__codelineno-91-7" name="__codelineno-91-7" href="#__codelineno-91-7"></a><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="o">:</span><span class="w"> </span><span class="kt">TreeNode</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nx">TreeNode</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-91-8" name="__codelineno-91-8" href="#__codelineno-91-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">node</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-91-9" name="__codelineno-91-9" href="#__codelineno-91-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-91-9" name="__codelineno-91-9" href="#__codelineno-91-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-91-10" name="__codelineno-91-10" href="#__codelineno-91-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-91-11" name="__codelineno-91-11" href="#__codelineno-91-11"></a><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">removeHelper</span><span class="p">(</span><span class="nx">node</span><span class="p">.</span><span class="nx">left</span><span class="p">,</span><span class="w"> </span><span class="nx">val</span><span class="p">);</span>
<a id="__codelineno-91-12" name="__codelineno-91-12" href="#__codelineno-91-12"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="nx">node</span><span class="p">.</span><span class="nx">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -5853,7 +5853,7 @@
<a id="__codelineno-92-6" name="__codelineno-92-6" href="#__codelineno-92-6"></a><span class="cm">/* 递归删除节点(辅助方法) */</span>
<a id="__codelineno-92-7" name="__codelineno-92-7" href="#__codelineno-92-7"></a><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">TreeNode</span><span class="o">?</span><span class="w"> </span><span class="n">node</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-92-8" name="__codelineno-92-8" href="#__codelineno-92-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-92-9" name="__codelineno-92-9" href="#__codelineno-92-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-92-9" name="__codelineno-92-9" href="#__codelineno-92-9"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-92-10" name="__codelineno-92-10" href="#__codelineno-92-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
<a id="__codelineno-92-11" name="__codelineno-92-11" href="#__codelineno-92-11"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-92-12" name="__codelineno-92-12" href="#__codelineno-92-12"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">val</span><span class="p">)</span>
@@ -5895,7 +5895,7 @@
<a id="__codelineno-93-7" name="__codelineno-93-7" href="#__codelineno-93-7"></a><span class="k">fn</span> <span class="nf">remove_helper</span><span class="p">(</span><span class="n">node</span>: <span class="nc">OptionTreeNodeRc</span><span class="p">,</span><span class="w"> </span><span class="n">val</span>: <span class="kt">i32</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">OptionTreeNodeRc</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-93-8" name="__codelineno-93-8" href="#__codelineno-93-8"></a><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-93-9" name="__codelineno-93-9" href="#__codelineno-93-9"></a><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">node</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-93-10" name="__codelineno-93-10" href="#__codelineno-93-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-93-10" name="__codelineno-93-10" href="#__codelineno-93-10"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-93-11" name="__codelineno-93-11" href="#__codelineno-93-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">borrow</span><span class="p">().</span><span class="n">val</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-93-12" name="__codelineno-93-12" href="#__codelineno-93-12"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">borrow</span><span class="p">().</span><span class="n">left</span><span class="p">.</span><span class="n">clone</span><span class="p">();</span>
<a id="__codelineno-93-13" name="__codelineno-93-13" href="#__codelineno-93-13"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="n">borrow_mut</span><span class="p">().</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">Self</span>::<span class="n">remove_helper</span><span class="p">(</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
@@ -5954,7 +5954,7 @@
<a id="__codelineno-94-10" name="__codelineno-94-10" href="#__codelineno-94-10"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">NULL</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-94-11" name="__codelineno-94-11" href="#__codelineno-94-11"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">NULL</span><span class="p">;</span>
<a id="__codelineno-94-12" name="__codelineno-94-12" href="#__codelineno-94-12"></a><span class="w"> </span><span class="p">}</span>
<a id="__codelineno-94-13" name="__codelineno-94-13" href="#__codelineno-94-13"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-94-13" name="__codelineno-94-13" href="#__codelineno-94-13"></a><span class="w"> </span><span class="cm">/* 1. 查找节点并删除 */</span>
<a id="__codelineno-94-14" name="__codelineno-94-14" href="#__codelineno-94-14"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-94-15" name="__codelineno-94-15" href="#__codelineno-94-15"></a><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="o">-&gt;</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-94-16" name="__codelineno-94-16" href="#__codelineno-94-16"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="o">-&gt;</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
@@ -6002,7 +6002,7 @@
<a id="__codelineno-95-7" name="__codelineno-95-7" href="#__codelineno-95-7"></a><span class="k">fn</span><span class="w"> </span><span class="n">removeHelper</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Self</span><span class="p">,</span><span class="w"> </span><span class="n">node_</span><span class="o">:</span><span class="w"> </span><span class="o">?*</span><span class="n">inc</span><span class="p">.</span><span class="n">TreeNode</span><span class="p">(</span><span class="n">T</span><span class="p">),</span><span class="w"> </span><span class="n">val</span><span class="o">:</span><span class="w"> </span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="o">?*</span><span class="n">inc</span><span class="p">.</span><span class="n">TreeNode</span><span class="p">(</span><span class="n">T</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-95-8" name="__codelineno-95-8" href="#__codelineno-95-8"></a><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">node</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">node_</span><span class="p">;</span>
<a id="__codelineno-95-9" name="__codelineno-95-9" href="#__codelineno-95-9"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">node</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
<a id="__codelineno-95-10" name="__codelineno-95-10" href="#__codelineno-95-10"></a><span class="w"> </span><span class="c1">// 1. 查找节点并删除</span>
<a id="__codelineno-95-10" name="__codelineno-95-10" href="#__codelineno-95-10"></a><span class="w"> </span><span class="c1">// 1. 查找节点并删除</span>
<a id="__codelineno-95-11" name="__codelineno-95-11" href="#__codelineno-95-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&lt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
<a id="__codelineno-95-12" name="__codelineno-95-12" href="#__codelineno-95-12"></a><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">left</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">removeHelper</span><span class="p">(</span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">left</span><span class="p">,</span><span class="w"> </span><span class="n">val</span><span class="p">);</span>
<a id="__codelineno-95-13" name="__codelineno-95-13" href="#__codelineno-95-13"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">val</span><span class="w"> </span><span class="o">&gt;</span><span class="w"> </span><span class="n">node</span><span class="p">.</span><span class="o">?</span><span class="p">.</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
+5 -7
View File
@@ -1830,7 +1830,7 @@
<span class="md-ellipsis">
8.3 &nbsp; Top-K 问题
8.3 &nbsp; Top-k 问题
</span>
@@ -3909,8 +3909,8 @@
<h3 id="2">2. &nbsp; 插入节点<a class="headerlink" href="#2" title="Permanent link">&para;</a></h3>
<p>给定一个待插入元素 <code>num</code> ,为了保持二叉搜索树“左子树 &lt; 根节点 &lt; 右子树”的性质,插入操作流程如图 7-18 所示。</p>
<ol>
<li><strong>查找插入位置</strong>:与查找操作相似,从根节点出发,根据当前节点值和 <code>num</code> 的大小关系循环向下搜索,直到越过叶节点(遍历至 <span class="arithmatex">\(\text{None}\)</span> )时跳出循环。</li>
<li><strong>在该位置插入节点</strong>:初始化节点 <code>num</code> ,将该节点置于 <span class="arithmatex">\(\text{None}\)</span> 的位置。</li>
<li><strong>查找插入位置</strong>:与查找操作相似,从根节点出发,根据当前节点值和 <code>num</code> 的大小关系循环向下搜索,直到越过叶节点(遍历至 <code>None</code> )时跳出循环。</li>
<li><strong>在该位置插入节点</strong>:初始化节点 <code>num</code> ,将该节点置于 <code>None</code> 的位置。</li>
</ol>
<p><a class="glightbox" href="../binary_search_tree.assets/bst_insert.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="在二叉搜索树中插入节点" class="animation-figure" src="../binary_search_tree.assets/bst_insert.png" /></a></p>
<p align="center"> 图 7-18 &nbsp; 在二叉搜索树中插入节点 </p>
@@ -3918,7 +3918,7 @@
<p>在代码实现中,需要注意以下两点。</p>
<ul>
<li>二叉搜索树不允许存在重复节点,否则将违反其定义。因此,若待插入节点在树中已存在,则不执行插入,直接返回。</li>
<li>为了实现插入节点,我们需要借助节点 <code>pre</code> 保存上一轮循环的节点。这样在遍历至 <span class="arithmatex">\(\text{None}\)</span> 时,我们可以获取到其父节点,从而完成节点插入操作。</li>
<li>为了实现插入节点,我们需要借助节点 <code>pre</code> 保存上一轮循环的节点。这样在遍历至 <code>None</code> 时,我们可以获取到其父节点,从而完成节点插入操作。</li>
</ul>
<div class="tabbed-set tabbed-alternate" data-tabs="3:12"><input checked="checked" id="__tabbed_3_1" name="__tabbed_3" type="radio" /><input id="__tabbed_3_2" name="__tabbed_3" type="radio" /><input id="__tabbed_3_3" name="__tabbed_3" type="radio" /><input id="__tabbed_3_4" name="__tabbed_3" type="radio" /><input id="__tabbed_3_5" name="__tabbed_3" type="radio" /><input id="__tabbed_3_6" name="__tabbed_3" type="radio" /><input id="__tabbed_3_7" name="__tabbed_3" type="radio" /><input id="__tabbed_3_8" name="__tabbed_3" type="radio" /><input id="__tabbed_3_9" name="__tabbed_3" type="radio" /><input id="__tabbed_3_10" name="__tabbed_3" type="radio" /><input id="__tabbed_3_11" name="__tabbed_3" type="radio" /><input id="__tabbed_3_12" name="__tabbed_3" type="radio" /><div class="tabbed-labels"><label for="__tabbed_3_1">Python</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Java</label><label for="__tabbed_3_4">C#</label><label for="__tabbed_3_5">Go</label><label for="__tabbed_3_6">Swift</label><label for="__tabbed_3_7">JS</label><label for="__tabbed_3_8">TS</label><label for="__tabbed_3_9">Dart</label><label for="__tabbed_3_10">Rust</label><label for="__tabbed_3_11">C</label><label for="__tabbed_3_12">Zig</label></div>
<div class="tabbed-content">
@@ -4310,9 +4310,7 @@
</div>
<p>与查找节点相同,插入节点使用 <span class="arithmatex">\(O(\log n)\)</span> 时间。</p>
<h3 id="3">3. &nbsp; 删除节点<a class="headerlink" href="#3" title="Permanent link">&para;</a></h3>
<p>先在二叉树中查找到目标节点,再将其删除。</p>
<p>与插入节点类似,我们需要保证在删除操作完成后,二叉搜索树的“左子树 &lt; 根节点 &lt; 右子树”的性质仍然满足。</p>
<p>因此,我们根据目标节点的子节点数量,分 0、1 和 2 三种情况,执行对应的删除节点操作。</p>
<p>先在二叉树中查找到目标节点,再将其删除。与插入节点类似,我们需要保证在删除操作完成后,二叉搜索树的“左子树 &lt; 根节点 &lt; 右子树”的性质仍然满足。因此,我们根据目标节点的子节点数量,分 0、1 和 2 三种情况,执行对应的删除节点操作。</p>
<p>如图 7-19 所示,当待删除节点的度为 <span class="arithmatex">\(0\)</span> 时,表示该节点是叶节点,可以直接删除。</p>
<p><a class="glightbox" href="../binary_search_tree.assets/bst_remove_case1.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="在二叉搜索树中删除节点(度为 0 )" class="animation-figure" src="../binary_search_tree.assets/bst_remove_case1.png" /></a></p>
<p align="center"> 图 7-19 &nbsp; 在二叉搜索树中删除节点(度为 0 ) </p>

Some files were not shown because too many files have changed in this diff Show More