Trie树结构
它的主要设计思想是空间换时间,利用字符串的公共前缀来降低查询时间的开销。它的优点是可以最大限度的减少无谓的字符串比较,查询效率比哈希表高;缺点是内存消耗非常大。
Trie树基本特性
- 根节点不包含字符,除根节点外每一个节点都只包含一个字符
- 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
- 每个节点的所有子节点包含的字符都不相同
Trie树的实现
插入单词(或者其他元素序列)过程中,需要对元素确定在“字典”中的序号,即hash。
(5)在某个节点处,关键词的所有字母都被取出,则读取附在节点上的信息,完成查找。
代码实现(c++)
#include<iostream>
#include<string.h>
using namespace std;
#define MAX_CHILD_NUM 26
struct TrieNode{
int count; //用来标记以根为起点以该节点为终点的路径上经过的字符是否构成字典中的字符串
TrieNode* childs[MAX_CHILD_NUM];
TrieNode(){
count = 0;
for (int i = 0; i < MAX_CHILD_NUM; i++){
childs[i] = NULL;
}
}
};
void Insert(TrieNode* root, char* str){
if (root == NULL){
return;
}
TrieNode* node = root;
char*p = str;
while (*p != '\0'){
if (node->childs[*p - 'a'] == NULL){
node->childs[*p - 'a'] = new TrieNode();
}
node = node->childs[*p - 'a'];
p++;
}
node->count++; //以该节点为终点可以构成一个单词
}
bool Search(TrieNode* root, char* str){
if (root == NULL){
return false;
}
TrieNode* node = root;
char* p = str;
while (*p != '\0'){
if (node->childs[*p - 'a'] == NULL){
break;
}
node = node->childs[*p - 'a'];
p++;
}
if (*p == '\0' && node->count){
return true;
}
return false;
}
void Delete(TrieNode* node){
if (node == NULL){
return;
}
for (int i = 0; i < MAX_CHILD_NUM; i++){
Delete(node->childs[i]);
}
delete[] node->childs;
}
int main(){
TrieNode* root = new TrieNode();
char* strs[] = {"hello", "world", "how", "are", "you"};
for (auto s : strs){
Insert(root, s);
}
cout << Search(root, "how") << endl;
cout << Search(root, "holy") << endl;
return 0;
}