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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

trie树 详解

發布時間:2023/11/27 生活经验 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 trie树 详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前幾天學習了并查集和trie樹,這里總結一下trie。
??? 本文討論一棵最簡單的trie樹,基于英文26個字母組成的字符串,討論插入字符串、判斷前綴是否存在、查找字符串等基本操作;至于trie樹的刪除單個節點實在是少見,故在此不做詳解。

l????????Trie原理

Trie的核心思想是空間換時間。利用字符串的公共前綴來降低查詢時間的開銷以達到提高效率的目的。

l????????Trie性質

好多人說trie的根節點不包含任何字符信息,我所習慣的trie根節點卻是包含信息的,而且認為這樣也方便,下面說一下它的性質 (基于本文所討論的簡單trie樹)

1.????字符的種數決定每個節點的出度,即branch數組(空間換時間思想)

2.????branch數組的下標代表字符相對于a的相對位置

3.????采用標記的方法確定是否為字符串。

4.????插入、查找的復雜度均為O(len),len為字符串長度

l????????Trie的示意圖

如圖所示,該trie樹存有abc、d、da、dda四個字符串,如果是字符串會在節點的尾部進行標記。沒有后續字符的branch分支指向NULL





l????????
Trie
Trie的優點舉例

已知n個由小寫字母構成的平均長度為10的單詞,判斷其中是否存在某個串為另一個串的前綴子串。下面對比3種方法:

1.????最容易想到的:即從字符串集中從頭往后搜,看每個字符串是否為字符串集中某個字符串的前綴,復雜度為O(n^2)。

2.????使用hash:我們用hash存下所有字符串的所有的前綴子串。建立存有子串hash的復雜度為O(n*len)。查詢的復雜度為O(n)* O(1)= O(n)。

3.????使用trie:因為當查詢如字符串abc是否為某個字符串的前綴時,顯然以b,c,d....等不是以a開頭的字符串就不用查找了。所以建立trie的復雜度為O(n*len),而建立+查詢在trie中是可以同時執行的,建立的過程也就可以成為查詢的過程,hash就不能實現這個功能。所以總的復雜度為O(n*len),實際查詢的復雜度只是O(len)。


解釋一下hash為什么不能將建立與查詢同時執行,例如有串:911,911456輸入,如果要同時執行建立與查詢,過程就是查詢911,沒有,然后存入9、91、911,查詢911456,沒有然后存入9114、91145、911456,而程序沒有記憶功能,并不知道911在輸入數據中出現過。所以用hash必須先存入所有子串,然后for循環查詢。

而trie樹便可以,存入911后,已經記錄911為出現的字符串,在存入911456的過程中就能發現而輸出答案;倒過來亦可以,先存入911456,在存入911時,當指針指向最后一個1時,程序會發現這個1已經存在,說明911必定是某個字符串的前綴,該思想是我在做pku上的3630中發現的,詳見本文配套的“入門練習”。

l????????Trie的簡單實現(插入、查詢)

?View Code

?
#include?<iostream>
using?namespace?std;
const?int?branchNum?=?26;?//聲明常量?
int?i;

struct?Trie_node
{
????bool?isStr;?//記錄此處是否構成一個串。
????Trie_node?*next[branchNum];//指向各個子樹的指針,下標0-25代表26字符
????Trie_node():isStr(false)
????{
????????memset(next,NULL,sizeof(next));
????}
};

class?Trie
{
public:
????Trie();
????void?insert(const?char*?word);
????bool?search(char*?word);?
????void?deleteTrie(Trie_node?*root);
private:
???Trie_node*?root;
};

Trie::Trie()
{
????root?=?new?Trie_node();
}
void?Trie::insert(const?char*?word)
{
????Trie_node?*location?=?root;
????while(*word)
????{
????????if(location->next[*word-'a']?==?NULL)//不存在則建立
????????{
????????????Trie_node?*tmp?=?new?Trie_node();
????????????location->next[*word-'a']?=?tmp;
????????}????
????????location?=?location->next[*word-'a'];?//每插入一步,相當于有一個新串經過,指針要向下移動
????????word++;
????}
????location->isStr?=?true;?//到達尾部,標記一個串
}

bool?Trie::search(char?*word)
{
????Trie_node?*location?=?root;
????while(*word?&&?location)
????{
????????location?=?location->next[*word-'a'];
????????word++;
????}
????return(location!=NULL?&&?location->isStr);
}

void?Trie::deleteTrie(Trie_node?*root)
{
????for(i?=?0;?i?<?branchNum;?i++)
????{
????????if(root->next[i]?!=?NULL)
????????{
????????????deleteTrie(root->next[i]);
????????}
????}
????delete?root;
}

void?main()?//簡單測試
{
????Trie?t;
????t.insert("a");?????????
????t.insert("abandon");
????char?*?c?=?"abandoned";
????t.insert(c);
????t.insert("abashed");
????if(t.search("abashed"))
????????printf("true\n");

?本文轉載自:http://www.cnblogs.com/cherish_yimi/archive/2009/10/12/1581666.html

?

?

轉載于:https://www.cnblogs.com/xufeiyang/articles/2469632.html

總結

以上是生活随笔為你收集整理的trie树 详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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