Trie原理:
http://blog.csdn.net/hguisu/article/details/8131559
http://powman.org/archives/trie.html
字典树:
根节点不包含字符(有数个指针指向其他节点),除根节点外每一个节点都只包含一个字符(可以理解为指针的连线的内容)。
从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串。
每个节点的所有子节点包含的字符都不相同(必须不相同)。
trie.h 内容
#ifndef _trie_tree_h
#define _trie_tree_h
#include <stack>
#include <memory>
const int base = 'a';
const int sonnum = 26;
class Trie{
private:
int num; // 公用路径的次数
bool isterminate; //是否有节点以本节点前面的边为终点
Trie *son[sonnum]; // 本节点对应的26个位置
public:
Trie():num(0),isterminate(false)
{
memset(son,NULL,sizeof(son));
}
void insertElem(Trie *root,char *s);
bool searchElem(Trie *root,char *s);
bool deleteElem(Trie *root,char *s);
void deleteAll(Trie *root);
};
#endif
trie.cpp 内容
#include "trie.h"
void Trie::insertElem(Trie *root,char *s)
{
printf("add '%s' to trie\n",s);
Trie *temp = root;
while(*s)
{
// find the path
if(temp->son[*s-base] != NULL)
++temp->num;
else
temp->son[*s-base] = new Trie();
temp = temp->son[*s-base];
++s;
}
// this point have the value
temp->isterminate = true;
}
bool Trie::searchElem(Trie *root,char *s)
{
Trie *temp = root;
int a =0;
while(*s)
{
// printf("%d\n",a++);
if(temp->son[*s-base]!=NULL)
temp = temp->son[*s-base];
else
return false;
++s;
}
if(temp->isterminate == false)
return false;
return true;
}
bool Trie::deleteElem(Trie *root,char *s)
{
Trie *cur = root;
std::stack <Trie *> nodes; // main function must using namespace std.
// go through our word, and record it in a stack
while(*s && cur!=NULL){
nodes.push(cur);
cur = cur->son[*s-base];
++s;
}
// end by this char
if(cur && cur->isterminate){
while(nodes.size() != 0){
char c = *(--s);
cur = nodes.top()->son[c-base];
// only this string using it
if(cur->num == 1)
{
delete cur;
nodes.top()->son[c-base] = NULL;
nodes.pop();
}else{
--cur->num;
nodes.pop();
while(nodes.size()!=0)
{
char *c = --s;
cur = nodes.top()->son[*c-base];
--cur->num;
nodes.pop();
}
break;
}
}
return true;
}else{ // not found in this trie
return false;
}
}
void Trie::deleteAll(Trie *root)
{
for(int i=0;i<sonnum;++i)
{
if(root->son[i]!=NULL)
deleteAll(root->son[i]);
}
delete root;
}
调用文件main.cpp
#include <iostream>
#include <conio.h>
#include "trie.h"
using namespace std;
int main()
{
Trie *ttree = new Trie;
ttree->insertElem(ttree,"a");
ttree->insertElem(ttree,"abandon");
ttree->insertElem(ttree,"abandoned");
if(ttree->searchElem(ttree,"abandon"))
cout<<"'abandon' Found Element!"<<endl;
else
cout<<"'abandon' Not Found!"<<endl;
ttree->insertElem(ttree,"badaf");
if(ttree->searchElem(ttree,"badl"))
cout<<"'badl' Found Element!"<<endl;
else
cout<<"'badl' Not Found!"<<endl;
getch();
}
插入复杂度是,O(N*len),其中len是平均插入字符长度。
删除复杂度是,单个单个删除也是O(N*len)
查找复杂度,即为len