Trie Tree (c + + implementation)

Source: Internet
Author: User

Ext.: http://www.cnblogs.com/kaituorensheng/p/3602155.html

http://blog.csdn.net/insistgogo/article/details/7828851

First, the definition:

Trie, also known as the Dictionary tree, is a 26-fork tree structure for fast retrieval. Typical space-changing time

Second, the structure diagram:

Three, the principle:

trie the keywords to be searched as a sequence of characters, and retrieves the tree structure according to the order of the characters of the keywords;

Specifically: Unlike a two-fork lookup tree, in a trie tree, one element is not stored on each node.

Four, the nature:

0, using the common prefix of the string, save memory

1. Searching on Trie tree always starts at the root node.

2, the root node does not contain characters, each node outside the root node represents only one letter, which is not included.

3, from the root node to a node, the path of the characters passed together, the string corresponding to the node.

4. All child nodes of each node contain different characters.

Five, efficiency analysis

0. When storing a large number of strings, trie consumes less space. Because the key value is not explicitly stored, the substring is shared with other key values.

1, query fast. The time to find a keyword in the trie tree is independent of the number of nodes that are contained in the tree, depending on how many characters make up the keyword. For a key with a length of M, the worst-case scenario would be to spend only O (m) time (compared to: two fork find Tree's lookup time and node number in the tree about O (log2n). )

2, if the keyword to be found can be decomposed into a character sequence and not very long, the use of Trie tree lookup speed is better than the binary search tree.

3, if the maximum keyword length is 5, then using the trie tree, 5 comparisons can be used to retrieve the specified keyword from 265 = 11,881,376 possible keywords. The binary search tree uses at least log2265=23.5 comparisons.

vi. application: used for the statistics and sorting of strings, often by the search engine system for text word frequency statistics.

1, the application of the dictionary tree in the fast retrieval of strings.

Give a cooked word list of n words, and an article written in lowercase English, please write all the new words that are not in the cooked vocabulary in the first order of occurrence. In this problem, we can use the dictionary tree, first put the cooked word to build a tree, and then read into the article to compare, this method of efficiency is relatively high.

2, the application of the Dictionary tree in "string" sorting

Given n a different English name consisting of only one word, let you sort them in dictionary order from small to large output with a dictionary tree, using an array of ways to create a dictionary tree, and all the sons of each node of the tree are clearly sorted by their letter size. This tree is preceded by a sequential traversal.

3. The application of the dictionary tree in the longest common prefix problem

To create a dictionary tree for all strings, the length of the longest public prefix for two strings is the number of common ancestors of their nodes, so the problem is transformed into the nearest common ancestor problem.

Code

Principle

First look at an example, storage string ABC, AB, ABM, ABCDE, PM can be stored in the following ways

Above is the basic principle of the trie tree: Use the common prefix of the string to save storage space, minimize unnecessary string comparisons.

Application

Trie tree is also called word search tree, the typical application is used for statistics, sorting and saving a large number of strings (not only for strings), so often used by the search engine system for text word frequency statistics.

Design

Trie, also known as a prefix tree or a dictionary tree, is an ordered tree that holds associative arrays, where the keys are usually strings. Unlike a two-fork lookup tree, a key is not stored directly in a node, but is determined by the position of the node in the tree. All descendants of a node have the same prefix, that is, the string corresponding to the node, and the root node corresponds to an empty string. In general, not all nodes have corresponding values, only the leaf node and some internal nodes corresponding to the key has the relevant value.

nodes can be designed like this:

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;          Stores the number of strings that end with this node        int nodesize;                Record the number of children in this node        trienode* children[size];    The array records pointers to children};

Icon

The tree is designed like this:

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 string Indexes are used (char% 26) to get, so ' a '% = +, ' b '% 26 = 20

Realize

Insert

To insert ABC, AB as an example

]

Delete

To delete a node, first find out if the string is in the tree, and if it is in the tree, then find out whether the following sections are all just one child, and each node has only a leaf node that is the end node, if not continue to repeat the top process down.

Number of statistics strings

In two different cases

    1. Count the number of repeated strings: is the end node, at which point the number of Terminabel is added
    2. Count the number of non-repeating strings: Is the end node, which adds 1 (when terminabel>0)

Reference Code

#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 + Strl En (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 (s TR));} Template<int Size, class Type>template<class Iterator>bool trie<size, type>::d Ownnodealone (    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 (c            Ur->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)) {eras        E (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->childre    N[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;}

Results

Technical Implementation Details

1. The deletion of trees is not a tree-destroying node, but is implemented by the node's own destructor.

2. Template class, template function, non-type template can refer to: http://www.cnblogs.com/kaituorensheng/p/3601495.html

3. The storage of letters is not the stored letter, but the location of the store, if the pointer is empty, it means there is no letter here;

4. Terminablenum stores the number of nodes to end with this node, which avoids the possibility of having multiple identical strings when the deletion is not known.

Trie Tree (c + + implementation)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.