程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Trie樹(c++實現)

Trie樹(c++實現)

編輯:C++入門知識

原理   先看個例子,存儲字符串abc、ab、abm、abcde、pm可以利用以下方式存儲             上邊就是Trie樹的基本原理:利用字串的公共前綴來節省存儲空間,最大限度的減少無謂的字串比較。   應用         Trie樹又稱單詞查找樹,典型的應用是用於統計,排序和保存大量的字符串(不僅用於字符串),所以經常被搜索引擎系統用於文本詞頻的統計。   設計         trie,又稱前綴樹或字典樹,是一種有序樹,用於保存關聯數組,其中的鍵通常是字符串。與二叉查找樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。一個節點的所有子孫都有相同的前綴,也就是這個節點對應的字符串,而根節點對應空字符串。一般情況下,不是所有的節點都有對應的值,只有葉子節點和部分內部節點所對應的鍵才有相關的值。   結點可以設計成這樣:   class trieNode {     public:         trieNode() : terminableSize(0), nodeSize(0) { for(int i = 0; i < Size; ++i) children[i] = NULL; }         ~trieNode()         {             for(int i = 0; i < Size; ++i)             {                 delete children[i];                 children[i] = NULL;             }         }     public:         int terminableSize;          //存儲以此結點為結尾的字串的個數         int nodeSize;                //記錄此結點孩子的個數         trieNode* children[Size];    //該數組記錄指向孩子的指針 };       樹設計成這樣:     template<int Size, class Type> class trie {     public:         typedef trieNode<Size> Node;         typedef trieNode<Size>* pNode;         trie() : root(new Node) {}           template<class Iterator>         void insert(Iterator beg, Iterator end);         void insert(const char *str);           template<class Iterator>         bool find(Iterator beg, Iterator end);         bool find(const char *str);           template<class Iterator>         bool downNodeAlone(Iterator beg);           template<class Iterator>         bool erase(Iterator beg, Iterator end);         bool erase(const char *str);           int sizeAll(pNode);         int sizeNoneRedundant(pNode);     public:         pNode root;     private:         Type index; };   index字串索引利用(char % 26) 得到,這樣'a' % 26 = 19, 'b' % 26 = 20   實現   插入   以插入abc、ab為例   ]           刪除   刪除結點,首先查找此字串是否在樹中,如果在樹中,再查找此結點以下的部分是不是都是只有一個孩子,並且每個結點只有葉子結點是結束結點,如果不是繼續往下重復上邊過程。   統計字串個數   分兩種情況   計算重復的字串的個數:是結束結點,此時加的是terminabel的個數 計算不重復的字串的個數:是結束結點,此時加的是1(當terminabel>0)的個數   #include <iostream> #include <cstring> using namespace std;   template<int Size> class trieNode {     public:         trieNode() : terminableSize(0), nodeSize(0) { for(int i = 0; i < Size; ++i) children[i] = NULL; }         ~trieNode()         {             for(int i = 0; i < Size; ++i)             {                 delete children[i];                 children[i] = NULL;             }         }     public:         int terminableSize;         int nodeSize;         trieNode* children[Size]; };   template<int Size, class Type> class trie {     public:         typedef trieNode<Size> Node;         typedef trieNode<Size>* pNode;         trie() : root(new Node) {}           template<class Iterator>         void insert(Iterator beg, Iterator end);         void insert(const char *str);           template<class Iterator>         bool find(Iterator beg, Iterator end);         bool find(const char *str);           template<class Iterator>         bool downNodeAlone(Iterator beg);           template<class Iterator>         bool erase(Iterator beg, Iterator end);         bool erase(const char *str);           int sizeAll(pNode);         int sizeNoneRedundant(pNode);     public:         pNode root;     private:         Type index; };   template<int Size, class Type> template<class Iterator> void trie<Size, Type>::insert(Iterator beg, Iterator end) {     pNode cur = root;     pNode pre;     for(; beg != end; ++beg)     {         if(!cur->children[index[*beg]])         {             cur->children[index[*beg]] = new(Node);             ++cur->nodeSize;         }         pre = cur;         cur = cur->children[index[*beg]];     }     ++pre->terminableSize; } template<int Size, class Type> void trie<Size, Type>::insert(const char *str) {     return insert(str, str + strlen(str)); }   template<int Size, class Type> template<class Iterator> bool trie<Size, Type>::find(Iterator beg, Iterator end) {     pNode cur = root;     pNode pre;     for(; beg != end; ++beg)     {         if(!cur->children[index[*beg]])         {             return false;             break;         }         pre = cur;         cur = cur->children[index[*beg]];     }     if(pre->terminableSize > 0)         return true;     return false; }   template<int Size, class Type> bool trie<Size, Type>::find(const char *str) {     return find(str, str + strlen(str)); }   template<int Size, class Type> template<class Iterator> bool trie<Size, Type>::downNodeAlone(Iterator beg) {     pNode cur = root;     int terminableSum = 0;     while(cur->nodeSize != 0)     {         terminableSum += cur->terminableSize;         if(cur->nodeSize > 1)             return false;         else          //cur->nodeSize = 1         {             for(int i = 0; i < Size; ++i)             {                 if(cur->children[i])                     cur = cur->children[i];             }         }     }     if(terminableSum == 1)         return true;     return false; } template<int Size, class Type> template<class Iterator> bool trie<Size, Type>::erase(Iterator beg, Iterator end) {     if(find(beg, end))     {         pNode cur = root;         pNode pre;         for(; beg != end; ++beg)         {             if(downNodeAlone(cur))             {                 delete cur;                 return true;             }             pre = cur;             cur = cur->children[index[*beg]];         }         if(pre->terminableSize > 0)             --pre->terminableSize;         return true;     }     return false; }   template<int Size, class Type> bool trie<Size, Type>::erase(const char *str) {     if(find(str))     {         erase(str, str + strlen(str));         return true;     }     return false; }   template<int Size, class Type> int trie<Size, Type>::sizeAll(pNode ptr) {     if(ptr == NULL)         return 0;     int rev = ptr->terminableSize;     for(int i = 0; i < Size; ++i)         rev += sizeAll(ptr->children[i]);     return rev; }   template<int Size, class Type> int trie<Size, Type>::sizeNoneRedundant(pNode ptr) {     if(ptr == NULL)         return 0;     int rev = 0;     if(ptr->terminableSize > 0)         rev = 1;     if(ptr->nodeSize != 0)     {         for(int i = 0; i < Size; ++i)             rev += sizeNoneRedundant(ptr->children[i]);     }     return rev; }   template<int Size> class Index {     public:         int operator[](char vchar)          { return vchar % Size; } };   int main() {     trie<26, Index<26> > t;     t.insert("hello");     t.insert("hello");     t.insert("h");     t.insert("h");     t.insert("he");     t.insert("hel");     cout << "SizeALL:" << t.sizeAll(t.root) << endl;     cout << "SizeALL:" << t.sizeNoneRedundant(t.root) << endl;     t.erase("h");     cout << "SizeALL:" << t.sizeAll(t.root) << endl;     cout << "SizeALL:" << t.sizeNoneRedundant(t.root) << endl; }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved