字典樹(tried)字首樹
阿新 • • 發佈:2020-12-02
字典樹又稱為字首樹,是一種用來統計字串字首數目的資料結構,字典樹的實現相對於線段樹等資料結構還是比較簡單。
字典樹的有3個核心函式,insert , search ,delete。
實現字典樹常用的方式有倆種,一個是結構體+指標,還用一種是二維陣列模擬,思想都是一樣的。
1、首先定義字典樹的節點:
class node{ public: int path; int end; node *mp[26]; node (){ path=end=0; for (int i=0;i<26;i++) mp[i]=NULL; } };
節點中的path用來記錄該節點被幾個字串用過。end用來記錄以該節點結尾的字串的個數。node *mp[26]是一個指標陣列,我們可以用該陣列記錄該節點指向的下一個節點,陣列大小為26指的是從a~z 26個英文字母,這個可以根據自己的尋求更改。比如說 x->mp[i]指的是節點x指向下一個值為i的節點。
2、節點的插入。
node *root = new node(); void insert(string s){ node *now=root; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; if(root->mp[id]==NULL){ root->mp[id]=new node(); } root=root->mp[id]; root->path++; } root->end++; root=now; }
首先定義一個根節點指標。然後遍歷字串S的每一個字元,root->mp[id]!=NULL,說明遍歷到目前為止,字首字串曾經出現過,即我們之前儲存過的字串和該字串有共同的字首。 如果root->mp[id]==NULL,說明該字首第一次出現,要新申請一個節點用來儲存當前字元,並作為上一個節點的兒子節點。
3、字串的查詢
int search(string s){ node *now=root; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; if(now->mp[id]!=NULL){ now=now->mp[id]; } else return 0;//不存在. } return now->path; }
查詢儲存過的字串無非就是根據字串s,從root出發能不能找到一條路徑。如果找著找著沒路了,即S沒有遍歷完遇到了NULL,那就沒找到嘍,否則返回path,意思的有樹中喲普幾個以該字串為字首的字串。
4、字串的刪除
void de(string s){ node *now=root; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; root->mp[id]->path--; if(root->mp[id]->path==0){ root->mp[id]=NULL; return ; } root=root->mp[id]; } root->end--; root=now; }
如果我們想要刪除之前儲存過的字串,只需要修改每個節點的path,如果說該節點的path為0了,直接將指標指為空即可並退出,如果沒有遇到path=0的情況,在最後節點的end--,說明以該節點為結尾的字串減一。
class node{ public: int path; int end; node *mp[26]; node (){ path=end=0; for (int i=0;i<26;i++) mp[i]=NULL; } }; node *root = new node(); void insert(string s){ node *now=root; if(root==NULL) return ; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; if(root->mp[id]==NULL){ root->mp[id]=new node(); } root=root->mp[id]; root->path++; } root->end++; root=now; } int search(string s){ node *now=root; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; if(now->mp[id]!=NULL){ now=now->mp[id]; } else return 0;//不存在. } return now->path; } void de(string s){ node *now=root; int n=s.size(); for(int i=0;i<n;i++){ int id=s[i]-'a'; root->mp[id]->path--; if(root->mp[id]->path==0){ root->mp[id]=NULL; return ; } root=root->mp[id]; } root->end--; root=now; }
root->path++;