Trie树可以用来进行高效的关键字检索,查询效率只跟要查询的关键字的长度相关,可跟hash相比拟。
有关Trie树的详细介绍,请参考http://linux.thai.net/~thep/datrie/datrie.html
这里给出了Trie树最简单的一种实现,即把Trie树看作有限状态自动机,用数组实现状态的转换。
#include <iostream>
#include <vector>
using namespace std;
class Node
{
public:
vector<Node *> next;
bool leaf;
Node():next(26, (Node *)NULL)
{
leaf = false;
}
};
class ArrayTrie
{
public:
Node root;
bool insert(const char*& key);
bool remove(const char*& key);
bool find(const char*& key);
};
bool ArrayTrie::insert(const char*& key)
{
Node* cur = &root; // cannot use the reference, because the reference cannot be rebound
int i = 0;
while( key[i] )
{
int pos = key[i] - 'a';
if( (cur->next).at(pos) == NULL )
(cur->next)[pos] = new Node();
cur = (cur->next)[pos];
++i;
}
return cur->leaf?false:(cur->leaf=true);
}
bool ArrayTrie::remove(const char*& key)
{
Node* cur = &root;
int i = 0;
while( key[i] )
{
int pos = key[i] - 'a';
if( (cur->next).at(pos) == NULL )
return false;
cur = (cur->next).at(pos);
++i;
}
cur->leaf = false;
return true;
}
bool ArrayTrie::find(const char*& key)
{
Node cur = root;
int i = 0;
while( key[i] )
{
int pos = key[i] - 'a';
if( (cur.next)[pos] == NULL )
return false;
cur = *( (cur.next).at(pos) );
++i;
}
return cur.leaf;
}
void Test()
{
ArrayTrie trie;
const char* str[] = {"baby", "badge", "bachelor", "jar", "java", "javac", "javap", "bad"};
for(int i = 0; i < 8; ++i)
{
bool r = trie.insert( str[i] );
if( r )
cout << "insert " << str[i] << endl;
else cout << "fail to insert " << str[i] << endl;
}
for(int i = 0; i < 8; ++i)
{
bool r = trie.find( str[i] );
if( r )
cout << "find " << str[i] << endl;
else cout << "fail to find " << str[i] << endl;
trie.remove( str[i] );
r = trie.find( str[i] );
if( r )
cout << "find " << str[i] << endl;
else cout << "fail to find " << str[i] << endl;
}
}
int main()
{
Test();
return 0;
}