This commit is contained in:
krahets
2025-01-02 21:38:22 +08:00
parent 2bbcdf6966
commit e6dbcc8008
327 changed files with 657 additions and 657 deletions
@@ -4803,7 +4803,7 @@ aria-label="頁脚"
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
</div>
@@ -5196,7 +5196,7 @@
<p>為了解決該問題,我們可以採用<u>懶刪除(lazy deletion</u>機制:它不直接從雜湊表中移除元素,<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>為此,考慮線性探查中記錄遇到的首個 <code>TOMBSTONE</code> 的索引,並將搜尋到的目標元素與該 <code>TOMBSTONE</code> 交換位置。這樣做的好處是當每次查詢或新增元素時,元素會被移動至距離理想位置(探測起始點)更近的桶,從而最佳化查詢效率。</p>
<p>以下程式碼實現了一個包含懶刪除的開放定址(線性探查)雜湊表。為了更加充分地使用雜湊表的空間,我們將雜湊表看作一個“環形陣列”,當越過陣列尾部時,回到頭部繼續走訪。</p>
<div class="tabbed-set tabbed-alternate" data-tabs="2:14"><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" /><input id="__tabbed_2_13" name="__tabbed_2" type="radio" /><input id="__tabbed_2_14" 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">Kotlin</label><label for="__tabbed_2_13">Ruby</label><label for="__tabbed_2_14">Zig</label></div>
<div class="tabbed-content">
@@ -7119,7 +7119,7 @@ aria-label="頁脚"
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
</div>
+1 -1
View File
@@ -5622,7 +5622,7 @@ aria-label="頁脚"
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
</div>
+1 -1
View File
@@ -3724,7 +3724,7 @@ aria-label="頁脚"
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
</div>
+2 -2
View File
@@ -3619,7 +3619,7 @@
<p>最後,雜湊表的時間複雜度可能發生劣化。例如在鏈式位址中,我們採取在鏈結串列或紅黑樹中執行查詢操作,仍然有退化至 <span class="arithmatex">\(O(n)\)</span> 時間的風險。</p>
<p><strong>Q</strong>:多次雜湊有不能直接刪除元素的缺陷嗎?標記為已刪除的空間還能再次使用嗎?</p>
<p>多次雜湊是開放定址的一種,開放定址法都有不能直接刪除元素的缺陷,需要透過標記刪除。標記為已刪除的空間可以再次使用。當將新元素插入雜湊表,並且透過雜湊函式找到標記為已刪除的位置時,該位置可以被新元素使用。這樣做既能保持雜湊表的探測序列不變,又能保證雜湊表的空間使用率。</p>
<p><strong>Q</strong>:為什麼線性探查中,查詢元素的時候會出現雜湊衝突呢?</p>
<p><strong>Q</strong>:為什麼線性探查中,查詢元素的時候會出現雜湊衝突呢?</p>
<p>查詢的時候透過雜湊函式找到對應的桶和鍵值對,發現 <code>key</code> 不匹配,這就代表有雜湊衝突。因此,線性探查法會根據預先設定的步長依次向下查詢,直至找到正確的鍵值對或無法找到跳出為止。</p>
<p><strong>Q</strong>:為什麼雜湊表擴容能夠緩解雜湊衝突?</p>
<p>雜湊函式的最後一步往往是對陣列長度 <span class="arithmatex">\(n\)</span> 取模(取餘),讓輸出值落在陣列索引範圍內;在擴容後,陣列長度 <span class="arithmatex">\(n\)</span> 發生變化,而 <code>key</code> 對應的索引也可能發生變化。原先落在同一個桶的多個 <code>key</code> ,在擴容後可能會被分配到多個桶中,從而實現雜湊衝突的緩解。</p>
@@ -3809,7 +3809,7 @@ aria-label="頁脚"
<div class="md-copyright">
<div class="md-copyright__highlight">
Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
</div>