hello-algo/zh-hant/docs/chapter_searching/searching_algorithm_revisited.md
Yudong Jin 5f7385c8a3
feat: Traditional Chinese version (#1163)
* First commit

* Update mkdocs.yml

* Translate all the docs to traditional Chinese

* Translate the code files.

* Translate the docker file

* Fix mkdocs.yml

* Translate all the figures from SC to TC

* 二叉搜尋樹 -> 二元搜尋樹

* Update terminology.

* Update terminology

* 构造函数/构造方法 -> 建構子
异或 -> 互斥或

* 擴充套件 -> 擴展

* constant - 常量 - 常數

* 類	-> 類別

* AVL -> AVL 樹

* 數組 -> 陣列

* 係統 -> 系統
斐波那契數列 -> 費波那契數列
運算元量 -> 運算量
引數 -> 參數

* 聯絡 -> 關聯

* 麵試 -> 面試

* 面向物件 -> 物件導向
歸併排序 -> 合併排序
范式 -> 範式

* Fix 算法 -> 演算法

* 錶示 -> 表示
反碼 -> 一補數
補碼 -> 二補數
列列尾部 -> 佇列尾部
區域性性 -> 區域性
一摞 -> 一疊

* Synchronize with main branch

* 賬號 -> 帳號
推匯 -> 推導

* Sync with main branch

* First commit

* Update mkdocs.yml

* Translate all the docs to traditional Chinese

* Translate the code files.

* Translate the docker file

* Fix mkdocs.yml

* Translate all the figures from SC to TC

* 二叉搜尋樹 -> 二元搜尋樹

* Update terminology

* 构造函数/构造方法 -> 建構子
异或 -> 互斥或

* 擴充套件 -> 擴展

* constant - 常量 - 常數

* 類	-> 類別

* AVL -> AVL 樹

* 數組 -> 陣列

* 係統 -> 系統
斐波那契數列 -> 費波那契數列
運算元量 -> 運算量
引數 -> 參數

* 聯絡 -> 關聯

* 麵試 -> 面試

* 面向物件 -> 物件導向
歸併排序 -> 合併排序
范式 -> 範式

* Fix 算法 -> 演算法

* 錶示 -> 表示
反碼 -> 一補數
補碼 -> 二補數
列列尾部 -> 佇列尾部
區域性性 -> 區域性
一摞 -> 一疊

* Synchronize with main branch

* 賬號 -> 帳號
推匯 -> 推導

* Sync with main branch

* Update terminology.md

* 操作数量(num. of operations)-> 操作數量

* 字首和->前綴和

* Update figures

* 歸 -> 迴
記憶體洩漏 -> 記憶體流失

* Fix the bug of the file filter

* 支援 -> 支持
Add zh-Hant/README.md

* Add the zh-Hant chapter covers.
Bug fixes.

* 外掛 -> 擴充功能

* Add the landing page for zh-Hant version

* Unify the font of the chapter covers for the zh, en, and zh-Hant version

* Move zh-Hant/ to zh-hant/

* Translate terminology.md to traditional Chinese
2024-04-06 02:30:11 +08:00

5.3 KiB
Raw Blame History

重識搜尋演算法

搜尋演算法searching algorithm用於在資料結構(例如陣列、鏈結串列、樹或圖)中搜索一個或一組滿足特定條件的元素。

搜尋演算法可根據實現思路分為以下兩類。

  • 透過走訪資料結構來定位目標元素,例如陣列、鏈結串列、樹和圖的走訪等。
  • 利用資料組織結構或資料包含的先驗資訊,實現高效元素查詢,例如二分搜尋、雜湊查詢和二元搜尋樹查詢等。

不難發現,這些知識點都已在前面的章節中介紹過,因此搜尋演算法對於我們來說並不陌生。在本節中,我們將從更加系統的視角切入,重新審視搜尋演算法。

暴力搜尋

暴力搜尋透過走訪資料結構的每個元素來定位目標元素。

  • “線性搜尋”適用於陣列和鏈結串列等線性資料結構。它從資料結構的一端開始,逐個訪問元素,直到找到目標元素或到達另一端仍沒有找到目標元素為止。
  • “廣度優先搜尋”和“深度優先搜尋”是圖和樹的兩種走訪策略。廣度優先搜尋從初始節點開始逐層搜尋,由近及遠地訪問各個節點。深度優先搜尋從初始節點開始,沿著一條路徑走到頭,再回溯並嘗試其他路徑,直到走訪完整個資料結構。

暴力搜尋的優點是簡單且通用性好,無須對資料做預處理和藉助額外的資料結構

然而,此類演算法的時間複雜度為 $O(n)$ ,其中 n 為元素數量,因此在資料量較大的情況下效能較差。

自適應搜尋

自適應搜尋利用資料的特有屬性(例如有序性)來最佳化搜尋過程,從而更高效地定位目標元素。

  • “二分搜尋”利用資料的有序性實現高效查詢,僅適用於陣列。
  • “雜湊查詢”利用雜湊表將搜尋資料和目標資料建立為鍵值對對映,從而實現查詢操作。
  • “樹查詢”在特定的樹結構(例如二元搜尋樹)中,基於比較節點值來快速排除節點,從而定位目標元素。

此類演算法的優點是效率高,時間複雜度可達到 O(\log n) 甚至 $O(1)$

然而,使用這些演算法往往需要對資料進行預處理。例如,二分搜尋需要預先對陣列進行排序,雜湊查詢和樹查詢都需要藉助額外的資料結構,維護這些資料結構也需要額外的時間和空間開銷。

!!! tip

自適應搜尋演算法常被稱為查詢演算法,**主要用於在特定資料結構中快速檢索目標元素**。

搜尋方法選取

給定大小為 n 的一組資料,我們可以使用線性搜尋、二分搜尋、樹查詢、雜湊查詢等多種方法從中搜索目標元素。各個方法的工作原理如下圖所示。

多種搜尋策略

上述幾種方法的操作效率與特性如下表所示。

表   查詢演算法效率對比

線性搜尋 二分搜尋 樹查詢 雜湊查詢
查詢元素 O(n) O(\log n) O(\log n) O(1)
插入元素 O(1) O(n) O(\log n) O(1)
刪除元素 O(n) O(n) O(\log n) O(1)
額外空間 O(1) O(1) O(n) O(n)
資料預處理 / 排序 O(n \log n) 建樹 O(n \log n) 建雜湊表 O(n)
資料是否有序 無序 有序 有序 無序

搜尋演算法的選擇還取決於資料體量、搜尋效能要求、資料查詢與更新頻率等。

線性搜尋

  • 通用性較好,無須任何資料預處理操作。假如我們僅需查詢一次資料,那麼其他三種方法的資料預處理的時間比線性搜尋的時間還要更長。
  • 適用於體量較小的資料,此情況下時間複雜度對效率影響較小。
  • 適用於資料更新頻率較高的場景,因為該方法不需要對資料進行任何額外維護。

二分搜尋

  • 適用於大資料量的情況,效率表現穩定,最差時間複雜度為 O(\log n)
  • 資料量不能過大,因為儲存陣列需要連續的記憶體空間。
  • 不適用於高頻增刪資料的場景,因為維護有序陣列的開銷較大。

雜湊查詢

  • 適合對查詢效能要求很高的場景,平均時間複雜度為 O(1)
  • 不適合需要有序資料或範圍查詢的場景,因為雜湊表無法維護資料的有序性。
  • 對雜湊函式和雜湊衝突處理策略的依賴性較高,具有較大的效能劣化風險。
  • 不適合資料量過大的情況,因為雜湊表需要額外空間來最大程度地減少衝突,從而提供良好的查詢效能。

樹查詢

  • 適用於海量資料,因為樹節點在記憶體中是分散儲存的。
  • 適合需要維護有序資料或範圍查詢的場景。
  • 在持續增刪節點的過程中,二元搜尋樹可能產生傾斜,時間複雜度劣化至 O(n)
  • 若使用 AVL 樹或紅黑樹,則各項操作可在 O(\log n) 效率下穩定執行,但維護樹平衡的操作會增加額外的開銷。