This commit is contained in:
krahets
2023-05-26 04:48:01 +08:00
parent 6ff9c19dfe
commit 2d3afc51c1
107 changed files with 1922 additions and 487 deletions

View File

@ -25,7 +25,7 @@
<title>11.9.   基数排序 - Hello 算法</title>
<title>11.10.   基数排序 - Hello 算法</title>
@ -79,7 +79,7 @@
<div data-md-component="skip">
<a href="#119" class="md-skip">
<a href="#1110" class="md-skip">
跳转至
</a>
@ -113,7 +113,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
11.9. &nbsp; 基数排序
11.10. &nbsp; 基数排序
</span>
</div>
@ -1411,6 +1411,8 @@
@ -1449,7 +1451,7 @@
<li class="md-nav__item">
<a href="../selection_sort/" class="md-nav__link">
11.2. &nbsp; 选择排序(New)
11.2. &nbsp; 选择排序New
</a>
</li>
@ -1517,9 +1519,23 @@
<li class="md-nav__item">
<a href="../heap_sort/" class="md-nav__link">
11.7. &nbsp; 堆排序New
</a>
</li>
<li class="md-nav__item">
<a href="../bucket_sort/" class="md-nav__link">
11.7. &nbsp; 桶排序
11.8. &nbsp; 桶排序
</a>
</li>
@ -1533,7 +1549,7 @@
<li class="md-nav__item">
<a href="../counting_sort/" class="md-nav__link">
11.8. &nbsp; 计数排序
11.9. &nbsp; 计数排序
</a>
</li>
@ -1556,12 +1572,12 @@
<label class="md-nav__link md-nav__link--active" for="__toc">
11.9. &nbsp; 基数排序
11.10. &nbsp; 基数排序
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
11.9. &nbsp; 基数排序
11.10. &nbsp; 基数排序
</a>
@ -1580,15 +1596,15 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#1191" class="md-nav__link">
11.9.1. &nbsp; 算法流程
<a href="#11101" class="md-nav__link">
11.10.1. &nbsp; 算法流程
</a>
</li>
<li class="md-nav__item">
<a href="#1192" class="md-nav__link">
11.9.2. &nbsp; 算法特性
<a href="#11102" class="md-nav__link">
11.10.2. &nbsp; 算法特性
</a>
</li>
@ -1609,7 +1625,7 @@
<li class="md-nav__item">
<a href="../summary/" class="md-nav__link">
11.10. &nbsp; 小结
11.11. &nbsp; 小结
</a>
</li>
@ -1854,15 +1870,15 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#1191" class="md-nav__link">
11.9.1. &nbsp; 算法流程
<a href="#11101" class="md-nav__link">
11.10.1. &nbsp; 算法流程
</a>
</li>
<li class="md-nav__item">
<a href="#1192" class="md-nav__link">
11.9.2. &nbsp; 算法特性
<a href="#11102" class="md-nav__link">
11.10.2. &nbsp; 算法特性
</a>
</li>
@ -1890,10 +1906,10 @@
<h1 id="119">11.9. &nbsp; 基数排序<a class="headerlink" href="#119" title="Permanent link">&para;</a></h1>
<h1 id="1110">11.10. &nbsp; 基数排序<a class="headerlink" href="#1110" title="Permanent link">&para;</a></h1>
<p>上一节我们介绍了计数排序,它适用于数据量 <span class="arithmatex">\(n\)</span> 较大但数据范围 <span class="arithmatex">\(m\)</span> 较小的情况。假设我们需要对 <span class="arithmatex">\(n = 10^6\)</span> 个学号进行排序,而学号是一个 <span class="arithmatex">\(8\)</span> 位数字,这意味着数据范围 <span class="arithmatex">\(m = 10^8\)</span> 非常大,使用计数排序需要分配大量内存空间,而基数排序可以避免这种情况。</p>
<p>「基数排序 Radix Sort」的核心思想与计数排序一致也通过统计个数来实现排序。在此基础上基数排序利用数字各位之间的递进关系依次对每一位进行排序从而得到最终的排序结果。</p>
<h2 id="1191">11.9.1. &nbsp; 算法流程<a class="headerlink" href="#1191" title="Permanent link">&para;</a></h2>
<h2 id="11101">11.10.1. &nbsp; 算法流程<a class="headerlink" href="#11101" title="Permanent link">&para;</a></h2>
<p>以学号数据为例,假设数字的最低位是第 <span class="arithmatex">\(1\)</span> 位,最高位是第 <span class="arithmatex">\(8\)</span> 位,基数排序的步骤如下:</p>
<ol>
<li>初始化位数 <span class="arithmatex">\(k = 1\)</span> </li>
@ -2450,7 +2466,7 @@ x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
<p class="admonition-title">为什么从最低位开始排序?</p>
<p>在连续的排序轮次中,后一轮排序会覆盖前一轮排序的结果。举例来说,如果第一轮排序结果 <span class="arithmatex">\(a &lt; b\)</span> ,而第二轮排序结果 <span class="arithmatex">\(a &gt; b\)</span> ,那么第二轮的结果将取代第一轮的结果。由于数字的高位优先级高于低位,我们应该先排序低位再排序高位。</p>
</div>
<h2 id="1192">11.9.2. &nbsp; 算法特性<a class="headerlink" href="#1192" title="Permanent link">&para;</a></h2>
<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>
@ -2534,7 +2550,7 @@ x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
<nav class="md-footer__inner md-grid" aria-label="页脚" >
<a href="../counting_sort/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 11.8. &amp;nbsp; 计数排序" rel="prev">
<a href="../counting_sort/" class="md-footer__link md-footer__link--prev" aria-label="上一页: 11.9. &amp;nbsp; 计数排序" rel="prev">
<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>
</div>
@ -2543,20 +2559,20 @@ x_k = \lfloor\frac{x}{d^{k-1}}\rfloor \bmod d
上一页
</span>
<div class="md-ellipsis">
11.8. &nbsp; 计数排序
11.9. &nbsp; 计数排序
</div>
</div>
</a>
<a href="../summary/" class="md-footer__link md-footer__link--next" aria-label="下一页: 11.10. &amp;nbsp; 小结" rel="next">
<a href="../summary/" class="md-footer__link md-footer__link--next" aria-label="下一页: 11.11. &amp;nbsp; 小结" rel="next">
<div class="md-footer__title">
<span class="md-footer__direction">
下一页
</span>
<div class="md-ellipsis">
11.10. &nbsp; 小结
11.11. &nbsp; 小结
</div>
</div>
<div class="md-footer__button md-icon">