Trie tree-detailed explanation of the dictionary tree !!
Also knownWord search tree,Trie treeIs a tree structure and a variant of the hash tree. A typical application is used for statistics, sorting, and saving a large number of strings (but not limited to strings). Therefore, it is often used by the search engine system for text word frequency statistics. It saves storage space by using the public prefix of strings and minimizes unnecessary string comparisons. The query efficiency is higher than that of hash tables.
The dictionary tree is very similar to the dictionary. When you want to check whether a word is in the dictionary tree, first check whether the first letter of the word is on the first layer of the dictionary. If not, it indicates that the word is not found in the dictionary tree. If the second letter of the word is found in the child node of the letter, it is not indicated that the word is not found, if yes, use the same method to continue searching. the dictionary tree can be used not only to store letters, but also to store numbers and other data.
Trie data structure definition:
# Define Max 26
Struct node // initial tire tree
{
Int num; // indicates whether the last character with the same prefix is used.
Node * Next [Max]; // subsequent Node
};
Next indicates the number of types in each layer. If it is only a lowercase letter, it can be 26. If it is changed to a case letter, it is 52. If it is added with a number, it is 62, this is determined based on the meaning of the question.
Sum indicates the number of identical prefixes in a dictionary tree. You should learn to change it as needed.
Trie search (the most important operation ):
(1) Each search starts from the root node;
(2) obtain the first letter of the keyword to be searched, select the corresponding subtree based on the letter, and go to the subtree for further search; (3) on the corresponding subtree, obtain the second letter of the keyword to be searched, and select the corresponding subtree for retrieval.
(4) iteration process ......
(5) If all the letters of a keyword have been removed from a node, the information attached to the node is read to complete the search.
The generated dictionary tree andTemplate:
Generate a dictionary tree:
Void insert (char ss []) // insert operation
{
Node * P = root, * t; // P points to the current node, t is used to open up memory
For (INT I = 0; SS [I]; I ++) // the process of saving each character
{
If (p-> next [ss [I]-'a'] = NULL) // when P points to null, a new node needs to be created.
{
T = new node;
T-> num = 0;
For (INT I = 0; I <Max; I ++)
T-> next [I] = NULL;
P-> next [ss [I]-'a'] = T; // connect to the new node.
}
P = p-> next [ss [I]-'a']; // P points to the next node.
P-> num ++ ;//
}
}
NextSearchThe process is:
Void search (char ss []) // search
{
Node * P = root; // P points to the root node
Int T = 0;
For (INT I = 0; SS [I]; I ++)
{
P = p-> next [ss [I]-'a']; // P points to the next node.
If (p-> num> 1)
{
TT [T] = ss [I];
T ++;
}
If (p-> num = 1)
{
TT [T] = ss [I];
TT [t + 1] = '\ 0 ';
Return;
}
}
TT [T] = '\ 0'; // This prevents the above p-> num from being greater than 1
Return;
}
The TT [] array is the prefix that can be differentiated by all strings.
Some summaries !!!!!!
Dynamic pointer version !!! The advantage code is short, the disadvantage is easy to exceed the memory, time-consuming
Struct node // initial tire tree
{
Int num; // indicates whether the last character with the same prefix is used.
Node * Next [Max]; // subsequent Node
};
Node * root; // create a reference for the root node
Void trie () // initial tire tree
{
Int I, J;
Root = new node; // open memory for the root node
Root-> num = 0;
For (INT I = 0; I <Max; I ++)
Root-> next [I] = NULL;
}
Void insert (char ss []) // insert operation
{
Node * P = root, * t; // P points to the current node, t is used to open up memory
For (INT I = 0; SS [I]; I ++) // the process of saving each character
{
If (p-> next [ss [I]-'a'] = NULL) // when P points to null, a new node needs to be created.
{
T = new node;
T-> num = 0;
For (INT I = 0; I <Max; I ++)
T-> next [I] = NULL;
P-> next [ss [I]-'a'] = T; // connect to the new node.
}
P = p-> next [ss [I]-'a']; // P points to the next node.
P-> num ++ ;//
}
}
Void search (char ss []) // search
{
Node * P = root; // P points to the root node
Int T = 0;
For (INT I = 0; SS [I]; I ++)
{
P = p-> next [ss [I]-'a']; // P points to the next node.
If (p-> num> 1)
{
TT [T] = ss [I];
T ++;
}
If (p-> num = 1)
{
TT [T] = ss [I];
TT [t + 1] = '\ 0 ';
Return;
}
}
TT [T] = '\ 0'; // This prevents the above p-> num from being greater than 1
Return;
}
The TT [] array is the prefix that can be differentiated by all strings.
Static edition !!!! Fast advantage
Struct Node
{
Bool isword;
Int next [Max];
Void Init ()
{
Memset (next, 0, sizeof (next ));
Isword = false;
}
} Tree [100010];
Void insert (char a [])
{
Int cou = 0;
Int Index = 0;
Int Len = strlen ();
For (INT I = 0; I <Len; I ++)
{
If (tree [Index]. Next [A [I]-'0'] = 0)
{
Tree [++ num]. INIT (); // create a new node
Tree [Index]. Next [A [I]-'0'] = num; // connect
Index = num;
}
Else
{
Cou ++;
Index = tree [Index]. Next [A [I]-'0'];
If (tree [Index]. isword)
{
OK = false;
Return;
}
}
}
Tree [Index]. isword = true;
If (COU = Len)
OK = false;
}
OK will return whether all strings have another prefix
Poj2001 poj2503 poj3630poj1056
Hope to be useful to everyone