字典樹 C++

字典樹c++實現

字典樹:

又稱單詞查找樹,Trie樹,是一種樹形結構,是一種哈希樹的變種。典型應用是用於統計,排序和保存大量的字符串(但不僅限於字符串),所以經常被搜索引擎系統用於文本詞頻統計。它的優點是:利用字符串的公共前綴來節約存儲空間,最大限度地減少無謂的字符串比較,查詢效率比哈希表高。

  字典樹的基本功能是用來查詢某個單詞(前綴)在所有單詞中出現次數的一種數據結構,它的插入和查詢複雜度都爲O(len),Len爲單詞(前綴)長度,但是它的空間複雜度卻非常高,如果字符集是26個字母,那每個節點的度就有26個,典型的以空間換時間結構。

下面我們選的存儲字典樹節點的數據結構爲:

typedef struct node
{
struct node *next[Max]; //表示對於每個節點最多有26個孩子節點
int num; //表示存儲的孩子節點的個數
}Node;

下面以一個例子爲例:給你100000個長度不超過10的單詞。對於每一個單詞,我們要判斷他出沒出現過。

假設我要查詢的單詞是abcd,那麼在他前面的單詞中,以b,c,d,f之類開頭的我顯然不必考慮。而只要找以a開頭的中是否存在abcd就可以了。同樣的,在以a開頭中的單詞中,我們只要考慮以b作爲第二個字母的……這樣一個樹的模型就漸漸清晰了……

字典樹代碼實現:

複製代碼
#include <iostream>
using namespace std;
#define Max 26
typedef struct node
{
    struct node *next[Max];
    int num;
}Node;
//創建一個新節點
Node *createNew()
{
    Node *p=new Node;
    for(int i=0;i<Max;i++)
    {
        p->next[i]=NULL;
    }
    p->num=0;
    return p;
}
//插入一個字符串
void Insert_str(char str[],Node *head)
{
    int len=strlen(str);
    Node *t,*p=head;
    for(int i=0;i<len;i++)
    {
        int c=str[i]-'a';
        if(p->next[c]==NULL)
        {

            t=createNew();
            p->next[c]=t;
            p->num++;
            //cout<<p->num<<endl;
             p=p->next[c];
        }
        else
        {
            p=p->next[c];
        }
    }
}
int Search_str(char str[],Node *head)
{
    Node *p=head;
    int len=strlen(str);
    int count=0;
    for(int i=0;i<len;i++)
    {
        int c=str[i]-'a';
        if(p->next[c]==NULL)
        {

            cout<<"不存在字符串"<<endl;
            count=0;
            return 0;
        }
        else
        {
            p=p->next[c];
            count=p->num;
        }


    }
    return count;
}
int main()
{
    cout<<"nihao"<<endl;
    Node *head=createNew();
    char s[10];
    while(cin>>s,strcmp(s,"quit"))
    {
        Insert_str(s,head);
    }
    int c=Search_str("abc",head);
    cout<<c<<endl;
    system("pause");


    return 0;
}

字典樹的典型應用:

1.統計一組字符串中某前綴出現的次數(直接用上面的代碼就行)。

2.判斷一組字符串中是否有一個字符串是另一個字符串的前綴。

分析:我們只要在結點中添加一個nEndFlag成員變量即可。若nEndFlag == 1,說明該結點字符是某一字符串的結尾(假設爲A),若在插入B字符串的過程中經過這一結點,則說明A是B的 前綴;還有一種情況,當要插入最後一個字符c時,卻發現p->next[c-'a']爲真,則說明該字符串是一個前綴字符串,eg:先插入abcde,再插入abc這種情況。

3. 串排序:給定N個互不相同的僅由一個單詞構成的英文名,讓你將他們按字典序從小到大輸出

  用字典樹進行排序,採用數組的方式創建字典樹,這棵樹的每個結點的所有兒子很顯然地按照其字母大小排序。對這棵樹進行先序遍歷即可。

 

該文章源地址:http://www.cnblogs.com/dlutxm/

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