Trie,又称字典树、单词查找树,是一种树形结构,用于保存大量的字符串。它的优点是:利用字符串的公共前缀来节约存储空间。
相对来说,Trie树是一种比较简单的数据结构.理解起来比较简单,正所谓简单的东西也得付出代价.故Trie树也有它的缺点,Trie树的内存消耗非常大.当然,或许用左儿子右兄弟的方法建树的话,可能会好点.
其基本性质可以归纳为:
1. 根节点不包含字符,除根节点外每一个节点都只包含一个字符。
2. 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
3. 每个节点的所有子节点包含的字符都不相同。
Trie.h
#ifndef Trie
#define Trie
#define Alphabet 26
#define BASE 'a'
typedef struct TrieNode{
bool terminal;
int num;
struct TrieNode* parent;
struct TrieNode* sons[Alphabet];
}TNode;
TNode * NewNode();
TNode* insert(TNode* root,const char* word,int len);
void deleteNode(TNode* root);
TNode* find(TNode* root,const char* word,int len);
#endif
Trie.cpp
#include "Trie.h"
#include "stddef.h"
TNode * NewNode(){
int i;
TNode* res = new TNode;
res->num = 1;
res->terminal = false;
for(i=0;i<Alphabet;i++) res->sons[i] = NULL;
return res;
}
TNode* insert(TNode* root,const char* word,int len){
int i;
TNode* tmp = root;
for(i=0;i<len;i++){
if(tmp->sons[word[i]-BASE] == NULL) {
tmp->sons[word[i]-BASE] = NewNode();
tmp->sons[word[i]-BASE]->parent = tmp;
}
else tmp->sons[word[i]-BASE]->num++;
tmp = tmp->sons[word[i]-BASE];
}
tmp->terminal = true;
return tmp;
}
void deleteNode(TNode* root){
if(root != NULL){
for(int i=0;i<Alphabet;i++) deleteNode(root->sons[i]);
delete root;
root = NULL;
}
}
TNode* find(TNode* root,const char* word,int len){
int i;
TNode* tmp = root;
for(i=0;i<len;i++){
if(tmp->sons[word[i] - BASE]!=NULL) tmp = tmp->sons[word[i] - BASE];
else return NULL;
}
return tmp;
}
main.cpp
#include"Trie.h"
#include<iostream>
#include<cstring>
#define MAXNUM 11
#define MAXLEN 11
using namespace std;
int n;
TNode* root = NewNode();
TNode* word[MAXNUM];
char words[MAXNUM][MAXLEN];
/*
5
cat
catac
catb
dele
dlel
*/
int main(){
int i;
cin >> n;
for(i=1;i<=n;i++){
cin >> words[i];
word[i] = insert(root,words[i],strlen(words[i]));
}
for(i=1;i<=n;i++){
TNode* tmp = word[i];
int size = strlen(words[i]);;
while(tmp->parent!=root&&tmp->parent->num == 1){
tmp = tmp->parent;
size--;
}
words[i][size]='/0';
cout << words[i] <<endl;
}
deleteNode(root);
}