字典樹(單詞查找樹)

1、數組

字典樹主要用於前綴搜索,字典樹不只能夠用來存儲字母,也能夠存儲數字等其餘數據。函數

2、spa

應用:統計、排序、保存大量字符串指針

原理:利用公共前綴,減小查詢時間和比較次數code

3、blog

特色:空間換時間排序

1.每個節點都有至少26個子節點(英文字母)內存

2.插入、查詢時間複雜度爲O(len)字符串

3.排序按照Trie樹先序遍歷class

節約空間

1.保存大量單詞的時候,相同前綴的空間共用。大部分字符串具備相同的前綴,即公共前綴。

2.每一個節點,對應一項前綴,葉子節點對應最長前綴,即單詞自己。

4、

性質:

1.根節點不包含字母

2.除根節點外,每一個節點包含一個字符

3.從根節點到某一節點的路徑,爲對應節點的字符串

4.每一個節點的全部子節點包含的字符均不一樣

5、

字典樹的靜態實現:

Trie樹定義:1.指向子節點的指針

2.當前節點的值

struct Trie//定義Trie樹節點結構體
{
    int value;//節點的值
    Trie *child[26];//指向的子節點的指針
    Trie()
    {
        value = 0;
        memset(child, NULL, sizeof(child));
    }
}*root;//根節點指針
//插入過程:1.從根節點開始,按照字母對應節點不斷向下
//2.直到單詞結束,在該節點上記錄單詞信息
void Insert(char str[])//插入字符串str
{
    Trie *x = root;//從根節點開始
    for (int i = 0; str[i]; i++)//逐個插入
    {
        int d = str[i] - 'a';
        //若子節點不存在,則new出對應節點
        if (x->child[d] == NULL)
            x->child[d] = new Trie;
        x = x->child[d];//轉成對應子樹
    }
    x->value++;//表示該單詞出現次數
}
//查找過程1.從根節點開始搜索
//2.獲得第一個字母節點後,轉到對應子樹
//3.在相應子樹繼續搜索下一個字母
//4.重複上述操做,直到到此結束,讀取節點信息
int Search(char str[])//查找字符串str
{
    Trie *x = root;//從根節點開始
    for (int i = 0; str[i]; i++)
    {
        int d = str[i] - 'a';
        if (x->child[d] == NULL)//查找失敗,直接退出
            return 0;
        x = x->child[d];//轉成對應子樹
    }
    return x->value;//查找成功,返回節點的值
}
//動態建立新節點
//1.釋放空間(delete),不然會後組數據影響而WA
//2.動態申請新節點耗時太多,數據量大容易TLE
void Deal(Trie *x)//釋放x爲根的子樹
{
    if (x == NULL)
        return;
    for (int i = 0; i < 26; i++)//釋放x的全部子節點
    {
        if (x->child[i] != NULL)
            Deal(x->child[i]);
    }
    delete x;//釋放x節點空間
}
//採用靜態方式
//注意做爲「內存」的數組大小,不然容易RE
struct Trie//定義Trie樹節點結構體
{
    int value;//節點的值
    int child[26];//指向的子節點的下標
    Trie()//構造函數
    {
        value = 0;
        memset(child, 0, sizeof(child));
    }
}trie[MAX];//靜態地址空間數組
int trieN = 0;//靜態數組下標,也表示節點數
//插入
void Insert(char str[])//插入字符串str
{
    int x = 0;//從根節點開始
    for (int i = 0; str[i]; i++)//逐個插入
    {
        int d = str[i] - 'a';
        if (trie[x].child[d] == 0)//在靜態數組末尾取一節點
        {
            trie[++trieN] = Trie();
            trie[x].child[d] = trieN;
        }
        x = trie[x].child[d];//轉成對應子樹
    }
    trie[x].value++;//表示該單詞出現次數
}

//查找
int Search(char str[])//查找字符串str
{
    int x = 0;//從根節點開始
    for (int i = 0; str[i]; i++)
    {
        int d = str[i] - 'a';
        if (trie[x].child[d] == 0)//查找失敗,直接退出
            return 0;
        x = trie[x].child[d];//轉成對應子樹
    }
    return trie[x].value;//查找成功,返回節點的值
}
相關文章
相關標籤/搜索