|
|
|
@ -1740,25 +1740,15 @@
|
|
|
|
|
<h2 id="1161">11.6.1. 简单实现<a class="headerlink" href="#1161" title="Permanent link">¶</a></h2>
|
|
|
|
|
<p>先看一个简单例子。给定一个长度为 <span class="arithmatex">\(n\)</span> 的数组 <code>nums</code> ,元素皆为 <strong>非负整数</strong>。计数排序的整体流程为:</p>
|
|
|
|
|
<ol>
|
|
|
|
|
<li>统计数组的最大数字,记为 <span class="arithmatex">\(m\)</span> ,并建立一个长度为 <span class="arithmatex">\(m + 1\)</span> 的辅助数组 <code>counter</code> ;</li>
|
|
|
|
|
<li>遍历记录数组中的最大数字,记为 <span class="arithmatex">\(m\)</span> ,并建立一个长度为 <span class="arithmatex">\(m + 1\)</span> 的辅助数组 <code>counter</code> ;</li>
|
|
|
|
|
<li><strong>借助 <code>counter</code> 统计 <code>nums</code> 中各数字的出现次数</strong>,其中 <code>counter[num]</code> 对应数字 <code>num</code> 的出现次数。统计方法很简单,只需遍历 <code>nums</code> (设当前数字为 <code>num</code>),每轮将 <code>counter[num]</code> 自增 <span class="arithmatex">\(1\)</span> 即可。</li>
|
|
|
|
|
<li><strong>由于 <code>counter</code> 的各个索引是天然有序的,因此相当于所有数字已经被排序好了</strong>。接下来,我们遍历 <code>counter</code> ,根据各数字的出现次数,将各数字按从小到大的顺序填入 <code>nums</code> 即可。</li>
|
|
|
|
|
</ol>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="1:3"><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" /><div class="tabbed-labels"><label for="__tabbed_1_1"><1></label><label for="__tabbed_1_2"><2></label><label for="__tabbed_1_3"><3></label></div>
|
|
|
|
|
<div class="tabbed-content">
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<p><img alt="counting_sort_naive_step1" src="../counting_sort.assets/counting_sort_naive_step1.png" /></p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<p><img alt="counting_sort_naive_step2" src="../counting_sort.assets/counting_sort_naive_step2.png" /></p>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<p><img alt="counting_sort_naive_step3" src="../counting_sort.assets/counting_sort_naive_step3.png" /></p>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<p>以下是实现代码,计数排序名副其实,确实是通过“统计数量”来实现排序的。</p>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="2:10"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1">Java</label><label for="__tabbed_2_2">C++</label><label for="__tabbed_2_3">Python</label><label for="__tabbed_2_4">Go</label><label for="__tabbed_2_5">JavaScript</label><label for="__tabbed_2_6">TypeScript</label><label for="__tabbed_2_7">C</label><label for="__tabbed_2_8">C#</label><label for="__tabbed_2_9">Swift</label><label for="__tabbed_2_10">Zig</label></div>
|
|
|
|
|
<p>观察发现,计数排序名副其实,是通过“统计元素数量”来实现排序的。</p>
|
|
|
|
|
<p><img alt="counting_sort_overview" src="../counting_sort.assets/counting_sort_overview.png" /></p>
|
|
|
|
|
<p align="center"> Fig. counting_sort_overview </p>
|
|
|
|
|
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="1:10"><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" /><div class="tabbed-labels"><label for="__tabbed_1_1">Java</label><label for="__tabbed_1_2">C++</label><label for="__tabbed_1_3">Python</label><label for="__tabbed_1_4">Go</label><label for="__tabbed_1_5">JavaScript</label><label for="__tabbed_1_6">TypeScript</label><label for="__tabbed_1_7">C</label><label for="__tabbed_1_8">C#</label><label for="__tabbed_1_9">Swift</label><label for="__tabbed_1_10">Zig</label></div>
|
|
|
|
|
<div class="tabbed-content">
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<div class="highlight"><span class="filename">counting_sort.java</span><pre><span></span><code><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="cm">/* 计数排序 */</span>
|
|
|
|
@ -1915,7 +1905,7 @@
|
|
|
|
|
<li>令前缀和 <code>prefix[num]</code> 自减 <span class="arithmatex">\(1\)</span> ,从而得到下次放置 <code>num</code> 的索引;</li>
|
|
|
|
|
</ol>
|
|
|
|
|
<p>完成遍历后,数组 <code>res</code> 中就是排序好的结果,最后使用 <code>res</code> 覆盖原数组 <code>nums</code> 即可;</p>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="3:8"><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" /><div class="tabbed-labels"><label for="__tabbed_3_1"><1></label><label for="__tabbed_3_2"><2></label><label for="__tabbed_3_3"><3></label><label for="__tabbed_3_4"><4></label><label for="__tabbed_3_5"><5></label><label for="__tabbed_3_6"><6></label><label for="__tabbed_3_7"><7></label><label for="__tabbed_3_8"><8></label></div>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="2:8"><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" /><div class="tabbed-labels"><label for="__tabbed_2_1"><1></label><label for="__tabbed_2_2"><2></label><label for="__tabbed_2_3"><3></label><label for="__tabbed_2_4"><4></label><label for="__tabbed_2_5"><5></label><label for="__tabbed_2_6"><6></label><label for="__tabbed_2_7"><7></label><label for="__tabbed_2_8"><8></label></div>
|
|
|
|
|
<div class="tabbed-content">
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<p><img alt="counting_sort_step1" src="../counting_sort.assets/counting_sort_step1.png" /></p>
|
|
|
|
@ -1944,7 +1934,7 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<p>计数排序的实现代码如下所示。</p>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="4:10"><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" /><input id="__tabbed_4_10" name="__tabbed_4" type="radio" /><div class="tabbed-labels"><label for="__tabbed_4_1">Java</label><label for="__tabbed_4_2">C++</label><label for="__tabbed_4_3">Python</label><label for="__tabbed_4_4">Go</label><label for="__tabbed_4_5">JavaScript</label><label for="__tabbed_4_6">TypeScript</label><label for="__tabbed_4_7">C</label><label for="__tabbed_4_8">C#</label><label for="__tabbed_4_9">Swift</label><label for="__tabbed_4_10">Zig</label></div>
|
|
|
|
|
<div class="tabbed-set tabbed-alternate" data-tabs="3:10"><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" /><div class="tabbed-labels"><label for="__tabbed_3_1">Java</label><label for="__tabbed_3_2">C++</label><label for="__tabbed_3_3">Python</label><label for="__tabbed_3_4">Go</label><label for="__tabbed_3_5">JavaScript</label><label for="__tabbed_3_6">TypeScript</label><label for="__tabbed_3_7">C</label><label for="__tabbed_3_8">C#</label><label for="__tabbed_3_9">Swift</label><label for="__tabbed_3_10">Zig</label></div>
|
|
|
|
|
<div class="tabbed-content">
|
|
|
|
|
<div class="tabbed-block">
|
|
|
|
|
<div class="highlight"><span class="filename">counting_sort.java</span><pre><span></span><code><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="cm">/* 计数排序 */</span>
|
|
|
|
|