淺談 trie樹 及其實現


定義又稱字典樹,單詞查找樹或者前綴樹,是一種用於快速檢索的多叉樹結構,

如英文字母的字典樹是一個26叉樹,數字的字典樹是一個10叉樹。

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

三個基本性質:

1. 根結點不包含字符,除根結點外每一個結點都只包含一個字符。

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

3. 每個結點的所有子結點包含的字符都不相同。

優點:利用字符串的公共前綴來節約存儲空間,最大限度地減少無謂的字符串比較,查詢效率比哈希表高。

缺點:如果存在大量字符串且這些字符串基本沒有公共前綴,則相應的trie樹將非常消耗內存。

典型應用:統計和排序大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計

至於Trie樹的實現,可以用數組,靜態分配空間,也可以用指針動態分配

Trie樹的操作

在Trie樹中主要有3個操作,插入、查找和刪。一般情況下Trie樹中很少存在刪除單獨某個結點的情況,因此只考慮刪除整棵樹。

假設存在字符串str(都為小寫字母),Trie樹的根結點為root。i=0,p=root。

typedef struct stu
{
    int n,flag;         //n記錄前綴及單詞的個數,flag標記單詞是否存在
    struct stu *next[26];          //子節點
}node;
View Code
node* creat_node()
{
    node *p=(node *)malloc(sizeof(node));
    p->n=p->flag=0;
    memset(p->next,0,sizeof(p->next));
    return p;
}
建立新節點並初始化

1、插入

  1)取str[i],判斷p->next[str[i]-'a']是否為空,若為空,則建立結點temp,並將p->next[str[i]-'a']指向temp,然后p指向temp;

   若不為空,則p=p->next[str[i]-'a'];

  2)i++,繼續取str[i],循環1)中的操作,直到遇到結束符'\0',此時將當前結點p中的 flag 置為true。

void trie_insert(node *p,char *s)
{
    int i;
    while(*s!='\0'){
        i=*s-'a';
        if(p->next[i]==0)
            p->next[i]=creat_node();
        p=p->next[i];
        s++;
        p->n++;
    }
    p->flag=1;
}
插入字符串

2、查找

  1)取str[i],判斷判斷p->next[str[i]-'a']是否為空,若為空,則返回false;若不為空,則p=p->next[str[i]-'a'],繼續取字符。

  2)重復1)中的操作直到遇到結束符'\0',若當前結點p不為空並且 flag 為true,則返回true,否則返回false。

int trie_search(node *p,char *s)
{
    int i;
    while(*s!='\0'){
        i=*s-'a';
        p=p->next[i];
        if(p==0)
            return 0;
        s++;
    }
    return p->n;
}
查找字符串,並返回其個數

3、刪除

  刪除可以以遞歸的形式進行刪除。

void trie_del(node *root)
{
    int i;
    for(i=0;i<M;i++)                     //M為子節點的個數
        if(root->next[i]!=NULL)
            trie_del(root->next[i]);
    free(root);
}
遞歸刪除整棵樹

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM