This commit is contained in:
krahets
2024-07-30 16:54:47 +08:00
parent 8fb4fdc14c
commit 55b91eb967
140 changed files with 426 additions and 1278 deletions
@@ -4035,8 +4035,7 @@
<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>自適應排序</strong>:在最差情況下,所有資料被分配到一個桶中,且排序該桶使用 <span class="arithmatex">\(O(n^2)\)</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> 時間。在最差情況下,所有資料被分配到一個桶中,且排序該桶使用 <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>桶排序是否穩定取決於排序桶內元素的演算法是否穩定。</li>
</ul>
@@ -4248,7 +4248,7 @@
</details>
<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 \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>
@@ -3626,11 +3626,10 @@
<a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a><span class="w"> </span><span class="o">(</span><span class="s1">&#39;C&#39;</span>,<span class="w"> </span><span class="m">21</span><span class="o">)</span>
<a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a><span class="w"> </span><span class="o">(</span><span class="s1">&#39;E&#39;</span>,<span class="w"> </span><span class="m">23</span><span class="o">)</span>
</code></pre></div>
<p><strong>自適應性</strong><u>自適應排序</u>的時間複雜度會受輸入資料的影響,即最佳時間複雜度、最差時間複雜度平均時間複雜度並不完全相等</p>
<p>自適應性需要根據具體情況來評估。如果最差時間複雜度差於平均時間複雜度,說明排序演算法在某些資料下效能可能劣化,因此被視為負面屬性;而如果最佳時間複雜度優於平均時間複雜度,則被視為正面屬性。</p>
<p><strong>自適應性</strong><u>自適應排序</u>能夠利用輸入資料已有的順序資訊來減少計算量,達到更優的時間效率。自適應排序演算法的最佳時間複雜度通常優於平均時間複雜度。</p>
<p><strong>是否基於比較</strong><u>基於比較的排序</u>依賴比較運算子(<span class="arithmatex">\(&lt;\)</span><span class="arithmatex">\(=\)</span><span class="arithmatex">\(&gt;\)</span>)來判斷元素的相對順序,從而排序整個陣列,理論最優時間複雜度為 <span class="arithmatex">\(O(n \log n)\)</span> 。而<u>非比較排序</u>不使用比較運算子,時間複雜度可達 <span class="arithmatex">\(O(n)\)</span> ,但其通用性相對較差。</p>
<h2 id="1112">11.1.2 &nbsp; 理想排序演算法<a class="headerlink" href="#1112" title="Permanent link">&para;</a></h2>
<p><strong>執行快、原地、穩定、正向自適應、通用性好</strong>。顯然,迄今為止尚未發現兼具以上所有特性的排序演算法。因此,在選擇排序演算法時,需要根據具體的資料特點和問題需求來決定。</p>
<p><strong>執行快、原地、穩定、自適應、通用性好</strong>。顯然,迄今為止尚未發現兼具以上所有特性的排序演算法。因此,在選擇排序演算法時,需要根據具體的資料特點和問題需求來決定。</p>
<p>接下來,我們將共同學習各種排序演算法,並基於上述評價維度對各個排序演算法的優缺點進行分析。</p>
<!-- Source file information -->
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 61 KiB

+1 -1
View File
@@ -3608,7 +3608,7 @@
<li>桶排序包含三個步驟:資料分桶、桶內排序和合並結果。它同樣體現了分治策略,適用於資料體量很大的情況。桶排序的關鍵在於對資料進行平均分配。</li>
<li>計數排序是桶排序的一個特例,它透過統計資料出現的次數來實現排序。計數排序適用於資料量大但資料範圍有限的情況,並且要求資料能夠轉換為正整數。</li>
<li>基數排序透過逐位排序來實現資料排序,要求資料能夠表示為固定位數的數字。</li>
<li>總的來說,我們希望找到一種排序演算法,具有高效率、穩定、原地以及正向自適應性等優點。然而,正如其他資料結構和演算法一樣,沒有一種排序演算法能夠同時滿足所有這些條件。在實際應用中,我們需要根據資料的特性來選擇合適的排序演算法。</li>
<li>總的來說,我們希望找到一種排序演算法,具有高效率、穩定、原地以及自適應性等優點。然而,正如其他資料結構和演算法一樣,沒有一種排序演算法能夠同時滿足所有這些條件。在實際應用中,我們需要根據資料的特性來選擇合適的排序演算法。</li>
<li>圖 11-19 對比了主流排序演算法的效率、穩定性、就地性和自適應性等。</li>
</ul>
<p><a class="glightbox" href="../summary.assets/sorting_algorithms_comparison.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="排序演算法對比" class="animation-figure" src="../summary.assets/sorting_algorithms_comparison.png" /></a></p>