日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

路径前缀是什么意思_Trie 树是什么样的数据结构?有哪些应用场景?

發布時間:2024/9/18 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 路径前缀是什么意思_Trie 树是什么样的数据结构?有哪些应用场景? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

(給算法愛好者加星標,修煉編程內功)

作者:神奕

blog.csdn.net/lisonglisonglisong/article/details/45584721

【前言】在計算機科學中,trie,又稱前綴樹字典樹,是一種有序樹,用于保存關聯數組,其中的鍵通常是字符串。

與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。

一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。

讓我們一起來學習下它吧。

一、什么是Trie樹

Trie樹,又叫字典樹、前綴樹(Prefix Tree)、單詞查找樹?或?鍵樹,是一種多叉樹結構。

如下圖:

上圖是一棵Trie樹,表示了關鍵字集合{“a”, “to”, “tea”, “ted”, “ten”, “i”, “in”, “inn”} 。從上圖可以歸納出Trie樹的基本性質:

  • 根節點不包含字符,除根節點外的每一個子節點都包含一個字符。

  • 從根節點到某一個節點,路徑上經過的字符連接起來,為該節點對應的字符串。

  • 每個節點的所有子節點包含的字符互不相同。

通常在實現的時候,會在節點結構中設置一個標志,用來標記該結點處是否構成一個單詞(關鍵字)。

可以看出,Trie樹的關鍵字一般都是字符串,而且Trie樹把每個關鍵字保存在一條路徑上,而不是一個結點中。

另外,兩個有公共前綴的關鍵字,在Trie樹中前綴部分的路徑相同,所以Trie樹又叫做前綴樹(Prefix Tree)。

二、Trie樹的優缺點

Trie樹的核心思想是空間換時間,利用字符串的公共前綴來減少無謂的字符串比較以達到提高查詢效率的目的。

優點

  • ????插入和查詢的效率很高,都為O(m)O(m),其中?m" role="presentation" style=" box-sizing: border-box; outline: 0px; display: inline; line-height: normal; word-spacing: normal; overflow-wrap: break-word; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">mm?是待插入/查詢的字符串的長度。

  • 關于查詢,會有人說 hash 表時間復雜度是O(1)" role="presentation" style=" box-sizing: border-box; outline: 0px; display: inline; line-height: normal; word-spacing: normal; overflow-wrap: break-word; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border-width: 0px; border-style: initial; border-color: initial; ">O(1)O(1)不是更快?但是,哈希搜索的效率通常取決于 hash 函數的好壞,若一個壞的 hash 函數導致很多的沖突,效率并不一定比Trie樹高。

  • Trie樹中不同的關鍵字不會產生沖突。

  • Trie樹只有在允許一個關鍵字關聯多個值的情況下才有類似hash碰撞發生。

  • Trie樹不用求 hash 值,對短字符串有更快的速度。通常,求hash值也是需要遍歷字符串的。

  • Trie樹可以對關鍵字按字典序排序。????

  • 缺點

  • 當 hash 函數很好時,Trie樹的查找效率會低于哈希搜索

  • 空間消耗比較大。

  • 三、Trie樹的應用

    1、字符串檢索

    檢索/查詢功能是Trie樹最原始的功能。思路就是從根節點開始一個一個字符進行比較:

    • 如果沿路比較,發現不同的字符,則表示該字符串在集合中不存在。

    • 如果所有的字符全部比較完并且全部相同,還需判斷最后一個節點的標志位(標記該節點是否代表一個關鍵字)。

    struct?trie_node{????bool isKey;???//?標記該節點是否代表一個關鍵字????trie_node *children[26];?//?各個子節點?};

    2、詞頻統計

    Trie樹常被搜索引擎系統用于文本詞頻統計 。

    struct?trie_node{????int count;???//?記錄該節點代表的單詞的個數????trie_node *children[26];?//?各個子節點?};

    思路:為了實現詞頻統計,我們修改了節點結構,用一個整型變量count來計數。對每一個關鍵字執行插入操作,若已存在,計數加1,若不存在,插入后count置1。

    注意:第一、第二種應用也都可以用 hash table 來做。

    3、字符串排序

    Trie樹可以對大量字符串按字典序進行排序,思路也很簡單:遍歷一次所有關鍵字,將它們全部插入trie樹,樹的每個結點的所有兒子很顯然地按照字母表排序,然后先序遍歷輸出Trie樹中所有關鍵字即可。

    4、前綴匹配

    例如:找出一個字符串集合中所有以ab開頭的字符串。我們只需要用所有字符串構造一個trie樹,然后輸出以a->b->開頭的路徑上的關鍵字即可。

    trie樹前綴匹配常用于搜索提示。如當輸入一個網址,可以自動搜索出可能的選擇。當沒有完全匹配的搜索結果,可以返回前綴最相似的可能。

    5、作為其他數據結構和算法的輔助結構

    如后綴樹,AC自動機等。

    四、Trie樹的實現

    這里為了方便,我們假設所有的關鍵字都由 a-z 的字母組成。

    下面是 trie 樹的一種典型實現:

    #include #include using namespace std;#define ALPHABET_SIZE 26typedef struct trie_node{ int count; // 記錄該節點代表的單詞的個數 trie_node *children[ALPHABET_SIZE]; // 各個子節點 }*trie;trie_node* create_trie_node(){ trie_node* pNode = new trie_node(); pNode->count = 0; for(int i=0; i pNode->children[i] = NULL; return pNode;}void trie_insert(trie root, char* key){ trie_node* node = root; char* p = key; while(*p) { if(node->children[*p-'a'] == NULL) { node->children[*p-'a'] = create_trie_node(); } node = node->children[*p-'a']; ++p; } node->count += 1;}/** * 查詢:不存在返回0,存在返回出現的次數 */ int trie_search(trie root, char* key){ trie_node* node = root; char* p = key; while(*p && node!=NULL) { node = node->children[*p-'a']; ++p; } if(node == NULL) return 0; else return node->count;}int main(){ // 關鍵字集合 char keys[][8] = {"the", "a", "there", "answer", "any", "by", "bye", "their"}; trie root = create_trie_node(); // 創建trie樹 for(int i = 0; i < 8; i++) trie_insert(root, keys[i]); // 檢索字符串 char s[][32] = {"Present in trie", "Not present in trie"}; printf("%s --- %s\n", "the", trie_search(root, "the")>0?s[0]:s[1]); printf("%s --- %s\n", "these", trie_search(root, "these")>0?s[0]:s[1]); printf("%s --- %s\n", "their", trie_search(root, "their")>0?s[0]:s[1]); printf("%s --- %s\n", "thaw", trie_search(root, "thaw")>0?s[0]:s[1]); return 0;}

    對于Trie樹,我們一般只實現插入和搜索操作。這段代碼可以用來檢索單詞和統計詞頻。

    - EOF -

    推薦閱讀??點擊標題可跳轉

    1、Trie樹的分析和理解

    2、巧用 Trie 樹實現搜索引擎關鍵詞提示功能

    3、字典樹入門

    覺得本文有幫助?請分享給更多人

    推薦關注「算法愛好者」,修煉編程內功

    點贊和在看就是最大的支持??

    總結

    以上是生活随笔為你收集整理的路径前缀是什么意思_Trie 树是什么样的数据结构?有哪些应用场景?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。