概述
字典树以前缀存取数据,就像文件系统一样,从根出发,只要知道某段数据的前缀,就能找到相应的数据。
同时,当存入新数据时,需建立新节点,然后将新数据依次插入对应字段。
本例中字典树以英文小写字母的基础数据。
首先,将字符串分层:以一个字母对应一层,即一个字母占用一个节点。
从根节点出发,寻找下一个字母所在节点,若没有,则建立一个新节点,然后依次迭代。
伪代码
struct Node
Node* child[26]
bool flag;
INSERT( S, Trie )
node = Trie.root
for i=0 to S.size
c = S[i] - 'a'
if node.child[c] == NULL
node.child[c] = new Node
node = node.child[c]
node.flag = true
FIND( S, Trie )
node = Trie.root
for i=0 to S.size
c = S[i] - 'a'
if node.child[c] == NULL
return false
node = node.child[c]
return node.flag
代码实现
const int SIZE = 26;
struct Node
{
struct Node* child[SIZE];
bool flag;
Node( void )
{
memset( this, 0, sizeof(Node) );
}
};
class Trie
{
public:
Trie( void );
~Trie( void );
void insert( const std::string str );
bool find( const std::string str );
void deleteTrie( Node* node );
private:
Node* root;
};
Trie::Trie( void )
{
root = new Node;
}
Trie::~Trie( void )
{
deleteTrie(root);
}
void Trie::deleteTrie( Node* node )
{
for( int i=0; i<SIZE; ++i ) {
if( node->child[i] != NULL ) {
deleteTrie( node->child[i] );
node->child[i] = NULL;
}
}
delete node;
node = NULL;
}
void Trie::insert( const std::string str )
{
int length = str.length();
Node* node = root;
for( int i=0; i<length; ++i ) {
int c = str[i] - 'a';
if( node->child[c] == NULL ) {
node->child[c] = new Node;
}
node = node->child[c];
}
node->flag = true;
}
bool Trie::find( const std::string str )
{
Node* node = root;
int length = str.length();
for( int i=0; i<length; ++i ) {
int c = str[i] - 'a';
if( node->child[c] == NULL ) {
return false;
}
node = node->child[c];
}
return node->flag;
}