This commit is contained in:
krahets
2024-03-21 04:22:16 +08:00
parent e5237ad99c
commit 5d9f0e656d
58 changed files with 1238 additions and 1216 deletions

View File

@@ -3883,48 +3883,47 @@ x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
<a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a><span class="kd">func</span> <span class="nf">countingSortDigit</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="n">exp</span><span class="p">:</span> <span class="nb">Int</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> <span class="c1">// 十进制的位范围为 0~9 ,因此需要长度为 10 的桶数组</span>
<a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> <span class="kd">var</span> <span class="nv">counter</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="mi">10</span><span class="p">)</span>
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="kd">let</span> <span class="nv">n</span> <span class="p">=</span> <span class="n">nums</span><span class="p">.</span><span class="bp">count</span>
<a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="c1">// 统计 0~9 各数字的出现次数</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">nums</span><span class="p">.</span><span class="bp">indices</span> <span class="p">{</span>
<a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="kd">let</span> <span class="nv">d</span> <span class="p">=</span> <span class="n">digit</span><span class="p">(</span><span class="n">num</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="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span> <span class="c1">// 获取 nums[i] 第 k 位,记为 d</span>
<a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1">// 统计数字 d 的出现次数</span>
<a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> <span class="p">}</span>
<a id="__codelineno-5-17" name="__codelineno-5-17" href="#__codelineno-5-17"></a> <span class="c1">// 求前缀和,将“出现个数”转换为“数组索引”</span>
<a id="__codelineno-5-18" name="__codelineno-5-18" href="#__codelineno-5-18"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">1</span> <span class="p">..</span><span class="o">&lt;</span> <span class="mi">10</span> <span class="p">{</span>
<a id="__codelineno-5-19" name="__codelineno-5-19" href="#__codelineno-5-19"></a> <span class="n">counter</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">counter</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<a id="__codelineno-5-20" name="__codelineno-5-20" href="#__codelineno-5-20"></a> <span class="p">}</span>
<a id="__codelineno-5-21" name="__codelineno-5-21" href="#__codelineno-5-21"></a> <span class="c1">// 倒序遍历,根据桶内统计结果,将各元素填入 res</span>
<a id="__codelineno-5-22" name="__codelineno-5-22" href="#__codelineno-5-22"></a> <span class="kd">var</span> <span class="nv">res</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="n">n</span><span class="p">)</span>
<a id="__codelineno-5-23" name="__codelineno-5-23" href="#__codelineno-5-23"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="bp">stride</span><span class="p">(</span><span class="n">from</span><span class="p">:</span> <span class="n">n</span> <span class="o">-</span> <span class="mi">1</span><span class="p">,</span> <span class="n">through</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="n">by</span><span class="p">:</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<a id="__codelineno-5-24" name="__codelineno-5-24" href="#__codelineno-5-24"></a> <span class="kd">let</span> <span class="nv">d</span> <span class="p">=</span> <span class="n">digit</span><span class="p">(</span><span class="n">num</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="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span>
<a id="__codelineno-5-25" name="__codelineno-5-25" href="#__codelineno-5-25"></a> <span class="kd">let</span> <span class="nv">j</span> <span class="p">=</span> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span> <span class="c1">// 获取 d 在数组中的索引 j</span>
<a id="__codelineno-5-26" name="__codelineno-5-26" href="#__codelineno-5-26"></a> <span class="n">res</span><span class="p">[</span><span class="n">j</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> <span class="c1">// 将当前元素填入索引 j</span>
<a id="__codelineno-5-27" name="__codelineno-5-27" href="#__codelineno-5-27"></a> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">1</span> <span class="c1">// 将 d 的数量减 1</span>
<a id="__codelineno-5-28" name="__codelineno-5-28" href="#__codelineno-5-28"></a> <span class="p">}</span>
<a id="__codelineno-5-29" name="__codelineno-5-29" href="#__codelineno-5-29"></a> <span class="c1">// 使用结果覆盖原数组 nums</span>
<a id="__codelineno-5-30" name="__codelineno-5-30" href="#__codelineno-5-30"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">nums</span><span class="p">.</span><span class="bp">indices</span> <span class="p">{</span>
<a id="__codelineno-5-31" name="__codelineno-5-31" href="#__codelineno-5-31"></a> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">=</span> <span class="n">res</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<a id="__codelineno-5-32" name="__codelineno-5-32" href="#__codelineno-5-32"></a> <span class="p">}</span>
<a id="__codelineno-5-33" name="__codelineno-5-33" href="#__codelineno-5-33"></a><span class="p">}</span>
<a id="__codelineno-5-34" name="__codelineno-5-34" href="#__codelineno-5-34"></a>
<a id="__codelineno-5-35" name="__codelineno-5-35" href="#__codelineno-5-35"></a><span class="cm">/* 基数排序 */</span>
<a id="__codelineno-5-36" name="__codelineno-5-36" href="#__codelineno-5-36"></a><span class="kd">func</span> <span class="nf">radixSort</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="p">{</span>
<a id="__codelineno-5-37" name="__codelineno-5-37" href="#__codelineno-5-37"></a> <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">m</span> <span class="p">=</span> <span class="nb">Int</span><span class="p">.</span><span class="bp">min</span>
<a id="__codelineno-5-39" name="__codelineno-5-39" href="#__codelineno-5-39"></a> <span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">nums</span> <span class="p">{</span>
<a id="__codelineno-5-40" name="__codelineno-5-40" href="#__codelineno-5-40"></a> <span class="k">if</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="n">m</span> <span class="p">{</span>
<a id="__codelineno-5-41" name="__codelineno-5-41" href="#__codelineno-5-41"></a> <span class="n">m</span> <span class="p">=</span> <span class="n">num</span>
<a id="__codelineno-5-42" name="__codelineno-5-42" href="#__codelineno-5-42"></a> <span class="p">}</span>
<a id="__codelineno-5-43" name="__codelineno-5-43" href="#__codelineno-5-43"></a> <span class="p">}</span>
<a id="__codelineno-5-44" name="__codelineno-5-44" href="#__codelineno-5-44"></a> <span class="c1">// 按照从低位到高位的顺序遍历</span>
<a id="__codelineno-5-45" name="__codelineno-5-45" href="#__codelineno-5-45"></a> <span class="k">for</span> <span class="n">exp</span> <span class="k">in</span> <span class="n">sequence</span><span class="p">(</span><span class="bp">first</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">next</span><span class="p">:</span> <span class="p">{</span> <span class="n">m</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="nv">$0</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span> <span class="p">?</span> <span class="nv">$0</span> <span class="o">*</span> <span class="mi">10</span> <span class="p">:</span> <span class="kc">nil</span> <span class="p">})</span> <span class="p">{</span>
<a id="__codelineno-5-46" name="__codelineno-5-46" href="#__codelineno-5-46"></a> <span class="c1">// 对数组元素的第 k 位执行计数排序</span>
<a id="__codelineno-5-47" name="__codelineno-5-47" href="#__codelineno-5-47"></a> <span class="c1">// k = 1 -&gt; exp = 1</span>
<a id="__codelineno-5-48" name="__codelineno-5-48" href="#__codelineno-5-48"></a> <span class="c1">// k = 2 -&gt; exp = 10</span>
<a id="__codelineno-5-49" name="__codelineno-5-49" href="#__codelineno-5-49"></a> <span class="c1">// 即 exp = 10^(k-1)</span>
<a id="__codelineno-5-50" name="__codelineno-5-50" href="#__codelineno-5-50"></a> <span class="n">countingSortDigit</span><span class="p">(</span><span class="n">nums</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">nums</span><span class="p">,</span> <span class="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span>
<a id="__codelineno-5-51" name="__codelineno-5-51" href="#__codelineno-5-51"></a> <span class="p">}</span>
<a id="__codelineno-5-52" name="__codelineno-5-52" href="#__codelineno-5-52"></a><span class="p">}</span>
<a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> <span class="c1">// 统计 0~9 各数字的出现次数</span>
<a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">nums</span><span class="p">.</span><span class="bp">indices</span> <span class="p">{</span>
<a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> <span class="kd">let</span> <span class="nv">d</span> <span class="p">=</span> <span class="n">digit</span><span class="p">(</span><span class="n">num</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="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span> <span class="c1">// 获取 nums[i] 第 k 位,记为 d</span>
<a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1">// 统计数字 d 的出现次数</span>
<a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> <span class="p">}</span>
<a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> <span class="c1">// 求前缀和,将“出现个数”转换为“数组索引”</span>
<a id="__codelineno-5-17" name="__codelineno-5-17" href="#__codelineno-5-17"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">1</span> <span class="p">..</span><span class="o">&lt;</span> <span class="mi">10</span> <span class="p">{</span>
<a id="__codelineno-5-18" name="__codelineno-5-18" href="#__codelineno-5-18"></a> <span class="n">counter</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+=</span> <span class="n">counter</span><span class="p">[</span><span class="n">i</span> <span class="o">-</span> <span class="mi">1</span><span class="p">]</span>
<a id="__codelineno-5-19" name="__codelineno-5-19" href="#__codelineno-5-19"></a> <span class="p">}</span>
<a id="__codelineno-5-20" name="__codelineno-5-20" href="#__codelineno-5-20"></a> <span class="c1">// 倒序遍历,根据桶内统计结果,将各元素填入 res</span>
<a id="__codelineno-5-21" name="__codelineno-5-21" href="#__codelineno-5-21"></a> <span class="kd">var</span> <span class="nv">res</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="n">nums</span><span class="p">.</span><span class="bp">count</span><span class="p">)</span>
<a id="__codelineno-5-22" name="__codelineno-5-22" href="#__codelineno-5-22"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">nums</span><span class="p">.</span><span class="bp">indices</span><span class="p">.</span><span class="n">reversed</span><span class="p">()</span> <span class="p">{</span>
<a id="__codelineno-5-23" name="__codelineno-5-23" href="#__codelineno-5-23"></a> <span class="kd">let</span> <span class="nv">d</span> <span class="p">=</span> <span class="n">digit</span><span class="p">(</span><span class="n">num</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="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span>
<a id="__codelineno-5-24" name="__codelineno-5-24" href="#__codelineno-5-24"></a> <span class="kd">let</span> <span class="nv">j</span> <span class="p">=</span> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">-</span> <span class="mi">1</span> <span class="c1">// 获取 d 在数组中的索引 j</span>
<a id="__codelineno-5-25" name="__codelineno-5-25" href="#__codelineno-5-25"></a> <span class="n">res</span><span class="p">[</span><span class="n">j</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> <span class="c1">// 将当前元素填入索引 j</span>
<a id="__codelineno-5-26" name="__codelineno-5-26" href="#__codelineno-5-26"></a> <span class="n">counter</span><span class="p">[</span><span class="n">d</span><span class="p">]</span> <span class="o">-=</span> <span class="mi">1</span> <span class="c1">// 将 d 的数量减 1</span>
<a id="__codelineno-5-27" name="__codelineno-5-27" href="#__codelineno-5-27"></a> <span class="p">}</span>
<a id="__codelineno-5-28" name="__codelineno-5-28" href="#__codelineno-5-28"></a> <span class="c1">// 使用结果覆盖原数组 nums</span>
<a id="__codelineno-5-29" name="__codelineno-5-29" href="#__codelineno-5-29"></a> <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="n">nums</span><span class="p">.</span><span class="bp">indices</span> <span class="p">{</span>
<a id="__codelineno-5-30" name="__codelineno-5-30" href="#__codelineno-5-30"></a> <span class="n">nums</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="p">=</span> <span class="n">res</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>
<a id="__codelineno-5-31" name="__codelineno-5-31" href="#__codelineno-5-31"></a> <span class="p">}</span>
<a id="__codelineno-5-32" name="__codelineno-5-32" href="#__codelineno-5-32"></a><span class="p">}</span>
<a id="__codelineno-5-33" name="__codelineno-5-33" href="#__codelineno-5-33"></a>
<a id="__codelineno-5-34" name="__codelineno-5-34" href="#__codelineno-5-34"></a><span class="cm">/* 基数排序 */</span>
<a id="__codelineno-5-35" name="__codelineno-5-35" href="#__codelineno-5-35"></a><span class="kd">func</span> <span class="nf">radixSort</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="p">{</span>
<a id="__codelineno-5-36" name="__codelineno-5-36" href="#__codelineno-5-36"></a> <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">m</span> <span class="p">=</span> <span class="nb">Int</span><span class="p">.</span><span class="bp">min</span>
<a id="__codelineno-5-38" name="__codelineno-5-38" href="#__codelineno-5-38"></a> <span class="k">for</span> <span class="n">num</span> <span class="k">in</span> <span class="n">nums</span> <span class="p">{</span>
<a id="__codelineno-5-39" name="__codelineno-5-39" href="#__codelineno-5-39"></a> <span class="k">if</span> <span class="n">num</span> <span class="o">&gt;</span> <span class="n">m</span> <span class="p">{</span>
<a id="__codelineno-5-40" name="__codelineno-5-40" href="#__codelineno-5-40"></a> <span class="n">m</span> <span class="p">=</span> <span class="n">num</span>
<a id="__codelineno-5-41" name="__codelineno-5-41" href="#__codelineno-5-41"></a> <span class="p">}</span>
<a id="__codelineno-5-42" name="__codelineno-5-42" href="#__codelineno-5-42"></a> <span class="p">}</span>
<a id="__codelineno-5-43" name="__codelineno-5-43" href="#__codelineno-5-43"></a> <span class="c1">// 按照从低位到高位的顺序遍历</span>
<a id="__codelineno-5-44" name="__codelineno-5-44" href="#__codelineno-5-44"></a> <span class="k">for</span> <span class="n">exp</span> <span class="k">in</span> <span class="n">sequence</span><span class="p">(</span><span class="bp">first</span><span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="n">next</span><span class="p">:</span> <span class="p">{</span> <span class="n">m</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="nv">$0</span> <span class="o">*</span> <span class="mi">10</span><span class="p">)</span> <span class="p">?</span> <span class="nv">$0</span> <span class="o">*</span> <span class="mi">10</span> <span class="p">:</span> <span class="kc">nil</span> <span class="p">})</span> <span class="p">{</span>
<a id="__codelineno-5-45" name="__codelineno-5-45" href="#__codelineno-5-45"></a> <span class="c1">// 对数组元素的第 k 位执行计数排序</span>
<a id="__codelineno-5-46" name="__codelineno-5-46" href="#__codelineno-5-46"></a> <span class="c1">// k = 1 -&gt; exp = 1</span>
<a id="__codelineno-5-47" name="__codelineno-5-47" href="#__codelineno-5-47"></a> <span class="c1">// k = 2 -&gt; exp = 10</span>
<a id="__codelineno-5-48" name="__codelineno-5-48" href="#__codelineno-5-48"></a> <span class="c1">// exp = 10^(k-1)</span>
<a id="__codelineno-5-49" name="__codelineno-5-49" href="#__codelineno-5-49"></a> <span class="n">countingSortDigit</span><span class="p">(</span><span class="n">nums</span><span class="p">:</span> <span class="p">&amp;</span><span class="n">nums</span><span class="p">,</span> <span class="n">exp</span><span class="p">:</span> <span class="n">exp</span><span class="p">)</span>
<a id="__codelineno-5-50" name="__codelineno-5-50" href="#__codelineno-5-50"></a> <span class="p">}</span>
<a id="__codelineno-5-51" name="__codelineno-5-51" href="#__codelineno-5-51"></a><span class="p">}</span>
</code></pre></div>
</div>
<div class="tabbed-block">