算法入門——字典樹(C++實現詳解)

字典樹(Trie)是處理字符串匹配的高效數據結構,廣泛應用于搜索提示、拼寫檢查等場景。本文將帶你從零掌握字典樹的原理與實現!

一、什么是字典樹?

字典樹(Trie)是一種樹形數據結構,用于高效存儲和檢索字符串集合。它的核心優勢在于:

  • 前綴共享:具有相同前綴的字符串共享樹中的路徑

  • 查找高效:查找時間復雜度僅與字符串長度相關(O(L))

  • 自動排序:存儲的字符串按字典序自動排列

典型應用場景:

  1. 搜索引擎的自動補全功能

  2. 拼寫檢查與單詞提示

  3. IP路由表的最長前綴匹配

  4. 單詞游戲(如Boggle、Scrabble)

二、字典樹的核心原理

基本結構

字典樹是一棵多叉樹,每個節點包含:

  • 指向子節點的指針數組(通常26個,對應26個字母)

  • 結束標記(標識從根到當前節點是否構成完整單詞)

工作方式

假設我們存儲單詞:["cat", "car", "dog"]

結構說明:

根節點 (root)
  • 不存儲具體字符

  • 包含指向所有首字母子節點的指針

字符節點
  • 每個節點存儲一個字符

  • 包含 26 個子指針(對應 a-z)

  • 示例路徑:

    • root → c → a → t?形成 "cat"

    • root → c → a → r?形成 "car"

    • root → d → o → g?形成 "dog"

單詞結束標記 (*)
  • 紅色節點表示單詞結束位置

  • t*?標記 "cat" 結束

  • r*?標記 "car" 結束

  • g*?標記 "dog" 結束

共享前綴機制
  • "cat" 和 "car" 共享?c→a?路徑

  • 節省存儲空間的關鍵特性

三、C++實現字典樹

節點結構設計

const int ALPHABET_SIZE = 26;class TrieNode {
public:TrieNode* children[ALPHABET_SIZE];bool isEndOfWord; // 標記是否單詞結束TrieNode() {isEndOfWord = false;for (int i = 0; i < ALPHABET_SIZE; i++) {children[i] = nullptr;}}
};

字典樹類框架

class Trie {
private:TrieNode* root;// 遞歸刪除節點(用于析構)void deleteTrie(TrieNode* node) {if (!node) return;for (int i = 0; i < ALPHABET_SIZE; i++) {if (node->children[i]) {deleteTrie(node->children[i]);}}delete node;}public:Trie() {root = new TrieNode();}~Trie() {deleteTrie(root);}// 插入單詞void insert(string word);// 搜索單詞(完全匹配)bool search(string word);// 檢查前綴是否存在bool startsWith(string prefix);
};

關鍵操作實現

1. 插入操作
void Trie::insert(string word) {TrieNode* current = root;for (char c : word) {int index = c - 'a';// 如果字符節點不存在則創建if (!current->children[index]) {current->children[index] = new TrieNode();}current = current->children[index];}current->isEndOfWord = true; // 標記單詞結束
}
2. 搜索操作
bool Trie::search(string word) {TrieNode* current = root;for (char c : word) {int index = c - 'a';if (!current->children[index]) {return false; // 字符不存在}current = current->children[index];}return current->isEndOfWord; // 檢查是否單詞結束
}
3. 前綴檢查
bool Trie::startsWith(string prefix) {TrieNode* current = root;for (char c : prefix) {int index = c - 'a';if (!current->children[index]) {return false;}current = current->children[index];}return true; // 前綴存在
}

四、復雜度分析

操作

時間復雜度

空間復雜度

插入單詞

O(L)

O(L)

搜索單詞

O(L)

O(1)

前綴檢查

O(L)

O(1)

L = 字符串長度

五、實戰應用:自動補全系統

// 獲取以指定前綴開頭的所有單詞
vector<string> getSuggestions(TrieNode* root, string prefix) {vector<string> suggestions;TrieNode* current = root;// 定位到前綴的最后一個節點for (char c : prefix) {int index = c - 'a';if (!current->children[index]) {return suggestions; // 前綴不存在}current = current->children[index];}// DFS收集所有單詞collectWords(current, prefix, suggestions);return suggestions;
}// DFS遍歷收集單詞
void collectWords(TrieNode* node, string currentWord, vector<string>& words) {if (!node) return;if (node->isEndOfWord) {words.push_back(currentWord);}for (int i = 0; i < ALPHABET_SIZE; i++) {if (node->children[i]) {char c = 'a' + i;collectWords(node->children[i], currentWord + c, words);}}
}

六、字典樹的優化方向

  1. 內存優化:使用vector動態存儲子節點(犧牲時間換空間)

  2. 刪除操作:添加引用計數支持安全刪除

  3. 壓縮字典樹:合并只有一個子節點的連續節點

  4. 支持Unicode:使用哈希表替代固定數組

七、總結與思考

字典樹的核心價值在于解決字符串前綴匹配問題。相比哈希表:

特性

字典樹

哈希表

前綴搜索

高效支持

不支持

內存占用

較高(空間換時間)

較低

查找效率

O(L)

O(1)平均

自動排序

支持

不支持

適用場景選擇:

  • 需要前綴匹配 → 字典樹

  • 僅需精確匹配 → 哈希表

  • 內存敏感場景 → 三向單詞查找樹

紙上得來終覺淺,絕知此事要躬行!建議嘗試實現字典樹后,在LeetCode上練習相關題目(如208, 211, 212題)鞏固理解。


擴展思考:如何修改字典樹結構使其支持中文?歡迎在評論區分享你的思路!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/87798.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/87798.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/87798.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SpringBoot整合SpringCache緩存

SpringBoot整合SpringCache使用緩存 文章目錄SpringBoot整合SpringCache使用緩存1.介紹2.SpringBoot整合1.導入xml依賴2.配置yml3.使用EnableCaching啟用SpringCache4.Cacheable5.CachePut6.CacheEvict7. Caching8.CacheConfig3.其他屬性配置1.keyGenerator 屬性2. cacheManage…

WPF學習筆記(20)Button與控件模板

Button與控件模板一、 Button默認控件模板詳解二、自定義按鈕模板一、 Button默認控件模板詳解 WPF 中的大多數控件都有默認的控件模板。 這些模板定義了控件的默認外觀和行為&#xff0c;包括控件的布局、背景、前景、邊框、內容等。 官方文檔&#xff1a;https://learn.mic…

藍天居士自傳(1)

藍天居士何許人&#xff1f; 藍天居士是我的筆名&#xff0c;也可以說是號。就好像李白號青蓮居士、歐陽修號六一居士一樣。筆者本名彭昊 —— 一個有不少重名重姓者的名字。 筆者小的時候上語文課&#xff0c;無論是小學、初中抑或是高中&#xff0c;都會有魯迅&#xff08;…

短劇系統開發定制全流程解析:從需求分析到上線的專業指南

一、短劇行業數字化趨勢與系統開發必要性在短視頻內容爆發式增長的時代背景下&#xff0c;短劇作為一種新興的內容形式正在迅速崛起。數據顯示&#xff0c;2023年中國短劇市場規模已突破300億元&#xff0c;用戶規模達到4.5億&#xff0c;年增長率超過200%。這一迅猛發展的市場…

getBoundingClientRect() 詳解:精準獲取元素位置和尺寸

getBoundingClientRect() 是 JavaScript 中一個強大的 DOM API&#xff0c;用于獲取元素在視口中的精確位置和尺寸信息。它返回一個 DOMRect 對象&#xff0c;包含元素的坐標、寬度和高度等關鍵幾何信息。 基本用法 const element document.getElementById(myElement); cons…

EXCEL 基礎技巧

來源&#xff1a;WPS 官網 初步了解WPS表格-WPS學堂https://www.wps.cn/learning/course/detail/id/635.html 1、格式刷 1.1使用格式刷隔行填充顏色。 首先設置部分表格顏色&#xff0c;選中此區域&#xff0c;雙擊點擊格式刷&#xff0c;然后選中其他表格區域。 這樣就可以…

【RK3568 編譯rtl8723DU驅動】

RK3568 編譯rtl8723DU驅動 編譯源碼1.解壓rtl8723du2.修改Makefile 驗證1.加載模塊2.開啟wifi 在驅動開發中&#xff0c;驅動的編譯與集成是實現設備功能的關鍵環節。本文聚焦于基于 RK3568 處理器平臺編譯 RTL8723DU WiFi/BT 二合一模塊驅動的完整流程&#xff0c;涵蓋源碼編譯…

基于Simulink的二關節機器人獨立PD控制仿真

文章目錄 理論模型仿真窗口控制函數目標函數仿真 本文是劉金琨. 機器人控制系統的設計與MATLAB仿真的學習筆記。 理論模型 對于二關節機器人系統&#xff0c;其動力學模型為 D ( q ) q C ( q , q ˙ ) q ˙ r D(q)\ddot qC(q,\dot q)\dot q r D(q)q?C(q,q˙?)q˙?r 式…

【技術架構解析】國產化雙復旦微FPGA+飛騰D2000核心板架構

本文就一款基于飛騰D2000核心板與兩片高性能FPGA的國產化開發主板進行技術解析&#xff0c;包括系統架構、主要硬件模塊、關鍵接口及軟件環境&#xff0c;重點闡述各子系統間的數據路徑與協同工作方式&#xff0c;旨在為行業內同類產品設計與應用提供參考。 隨著國產化要求的加…

Python 數據分析:計算,分組統計1,df.groupby()。聽故事學知識點怎么這么容易?

目錄1 示例代碼2 歡迎糾錯3 論文寫作/Python 學習智能體1 示例代碼 直接上代碼。 def grpby1():xls "book.xls"df pd.DataFrame(pd.read_excel(xls, engine"xlrd"))print(df)"""序號 分類 銷量0 1 文學 51 2 計算機…

【解決“此擴展可能損壞”】Edge瀏覽器(chrome系列通殺))擴展損壞?一招保留數據快速修復

引言 如果你想保留你的數據&#xff0c;敲重點&#xff1a;不要點擊修復&#xff0c;不要修復&#xff0c;不要修復 在使用 Microsoft Edge 瀏覽器時&#xff0c;您可能會遇到擴展程序顯示“此擴展程序可能已損壞”的提示&#xff0c;且啟用按鈕無法點擊。這一問題讓許多用戶感…

AI專業化應用加速落地,安全治理挑戰同步凸顯

7月2日&#xff0c;2025全球數字經濟大會在北京國家會議中心開幕。本屆大會以“建設數字友好城市”為主題&#xff0c;聚焦數字技術對城市發展的影響。開幕式上&#xff0c;一首完全由AI生成的MV成為焦點——從歌詞、譜曲、演唱到視頻制作全流程AI生成&#xff0c;展現人工智能…

Python統一調用多家大模型API指南

隨著大模型技術的快速發展&#xff0c;市場上出現了越來越多的LLM服務提供商&#xff0c;包括OpenAI、Anthropic、Google、百度、阿里云等。作為開發者&#xff0c;我們經常需要在不同的模型之間切換&#xff0c;或者同時使用多個模型來滿足不同的業務需求。本文將詳細介紹如何…

【ESP32】1.編譯、燒錄、創建工程

標題打開一個Hello world工程并燒錄 點擊環境搭建鏈接 遇到的問題&#xff1a; 1.ESP32在VSCODE中燒錄代碼時&#xff0c;跳出窗口&#xff0c;OPenOCD is not running ,do you want to launch it? 可能是OCD沒安裝&#xff0c;重新安裝 ESP-IDF試一下&#xff0c;在終端命令窗…

調參——optuna

它基于貝葉斯優化&#xff08;Bayesian Optimization&#xff09;思想&#xff0c;通過構建一個概率模型來預測超參數組合的性能&#xff0c;從而高效地探索超參數空間。相比傳統網格搜索&#xff08;Grid Search&#xff09;或隨機搜索&#xff08;Random Search&#xff09;&…

Redis的緩存擊穿和緩存雪崩

Redis緩存擊穿和緩存雪崩是兩種常見的緩存問題&#xff0c;它們都可能導致系統性能下降甚至崩潰。以下是對它們的詳細解釋&#xff1a;一、緩存擊穿定義緩存擊穿是指一個特定的緩存數據失效&#xff08;例如過期&#xff09;&#xff0c;而此時大量請求同時訪問這個數據&#x…

Python訓練營Day4

浙大疏錦行 Python訓練營Day4 內容&#xff0c;pandas處理表格信息&#xff1a; 查看表格統計信息&#xff1a; data.mean()data.mode()data.median() 查看表格信息&#xff1a; data.info()data.describe()data.isnull()data.head() 填充空缺列&#xff1a; 數值型&#xff…

React 基本介紹與項目創建

為什么使用 React 以及前端框架 工作原理 React 通過構建虛擬 DOM&#xff08;Virtual DOM&#xff09;來高效管理界面。當組件的狀態或屬性發生變化時&#xff0c;React 會重新渲染生成新的虛擬 DOM&#xff0c;并通過 Diff 算法找出新舊虛擬 DOM 樹之間的差異&#xff0c;最…

OpenCV CUDA模塊設備層-----“小于閾值設為零” 的圖像處理函數thresh_to_zero_func()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 OpenCV CUDA 模塊&#xff08;cudev&#xff09; 中的一個仿函數生成器&#xff0c;用于創建一個 “小于閾值設為零” 的圖像處理函數對象。 這個函…

數字圖像處理學習筆記

1-圖像處理基礎_嗶哩嗶哩_bilibili 輸出圖像像素點需要將圖象值要作類型轉換&#xff0c;轉成Int 圖像仿射變換 線性變換平移 線性變換&#xff1a; 1&#xff0c;變換前直線&#xff0c;變換后仍然直線 2&#xff0c;直線比例不變 3&#xff0c;直線到遠點的距離不變 仿射變…