Trie(前綴樹)

Trie (發音爲 "try") 或前綴樹是一種樹數據結構,用於檢索字符串數據集中的鍵。這一高效的數據結構有多種應用:1. 自動補全 2.拼寫檢查 3.九宮格打字預測 4.IP路由(最長前綴匹配)

爲什麼需要Trie樹結構?

哈希表可以在 O(1)O(1) 時間內尋找鍵值,卻無法高效的完成以下操作:

  • 找到具有同一前綴的全部鍵值。
  • 按詞典序枚舉字符串的數據集。


Trie 樹優於哈希表的另一個理由是,隨着哈希表大小增加,會出現大量的衝突,時間複雜度可能增加到 O(n),其中 n是插入的鍵的數量。與哈希表相比,Trie 樹在存儲多個具有相同前綴的鍵時可以使用較少的空間。此時 Trie 樹只需要 O(m)的時間複雜度,其中 m 爲鍵長。而在平衡樹中查找鍵值需要 O(mlogn) 時間複雜度。

Trie 樹的結點結構
Trie 樹是一個有根的樹,其結點具有以下字段:

  1. 最多 R 個指向子結點的鏈接,其中每個鏈接對應字母表數據集中的一個字母。本文中假定 R 爲 26,小寫拉丁字母的數量。
  2. 布爾字段,以指定節點是對應鍵的結尾還是隻是鍵前綴。

結構體如下:

struct TrieNode {
    bool isEnd; //該結點是否是一個串的結束
    TrieNode* next[26]; //字母映射表
};

初始化

 Trie() {
        for(int i=0;i<26;i++){
            root->nodes[i] = NULL;
        }
        root->isEnd = true;
}

插入

void insert(string word) {
        TrieNode * now  = root;
        for(char c : word){
            if(now->nodes[c-'a'] == NULL){
                now->nodes[c-'a'] = new TrieNode();
            }

            now= now->nodes[c-'a'];
        }
        now->isEnd =  true;
}

查找

bool search(string word) {
        TrieNode * now = root;
        for(char c : word){
            if(now->nodes[c-'a'] == NULL){
                return false;
            }
            now = now->nodes[c-'a'];
        }

        if(now->isEnd) return true;
        else return false;
}

 

判斷前綴

bool startsWith(string prefix) {
        TrieNode * now = root;
        for(char c:prefix){
            if(now->nodes[c-'a'] == NULL)
                return false;
            now = now->nodes[c-'a'];
        }
        return true;
}

 

參考自leetcode208題 實現Trie樹 題目鏈接 https://leetcode-cn.com/problems/implement-trie-prefix-tree/

前綴樹的應用:對字典實現單詞搜索 https://leetcode-cn.com/problems/word-search-ii/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章