问题描述:
1.Ternary Search Tree较之于Trie Tree也是一种前缀树(prefix tree),主要用于存储字符串,再对大量字符串进行查询和存储(insert)操作时有非常好的性能;
2.Ternary Search Tree vs Trie Tree有更好的空间效率:所占内存更少,对于存储相同的字符串集;
3.Ternary Search Tree每个节点有三个指针,分别指向小于,等于,大于此节点值(字符串中的一个字符)的各个孩子节点;
4.Ternary Search Tree的查询和插入的时间复杂度是lg(N),N是树中的节点树。因此,它的操作性能不如Trie Tree;
5.使用场景,拼写正确性检查;给定字符串字典和当前词,寻找下一个最邻近的词(尽量相同的前缀,不同的字符有不等关系);
程序代码:
#ifndef _TERNARY_SEARCH_TREE_H_
#define _TERNARY_SEARCH_TREE_H_
/*
* ternary search tree
*
*/
class TernarySearchTree
{
public:
// tree Node
typedef struct tagTernaryNode
{
char data;
char isLeaf;
tagTernaryNode* leftChild;
tagTernaryNode* midChild;
tagTernaryNode* rightChild;
tagTernaryNode():data(), isLeaf(), leftChild(0),
midChild(0),rightChild(0)
{
}
tagTernaryNode( char c ):data(c),isLeaf(),
leftChild(0), midChild(0),
rightChild(0)
{
}
}TernaryNode, *pTernaryNode;
/*
*
*
*/
TernarySearchTree():m_root(0),m_size(0)
{
}
/*
*
*
*/
~TernarySearchTree()
{
Clear();
}
/*
*Check empty
*
*/
bool IsEmpty() const
{
return m_size == 0;
}
/*
* Retrieve the number of node of tree
*
*/
size_t Size() const
{
return m_size;
}
/*
*Insert string to tree
*
*/
void Insert( const char* word )
{
Insert( m_root, word );
}
/*
*Search in term of given string
*
*/
bool Search( const char* word )
{
return Search( m_root, word );
}
/*
*Clear all node
*
*/
void Clear()
{
Clear( m_root );
m_size = 0;
}
private:
/*
* Implement search operation
*
*/
bool Search( pTernaryNode root, const char* word )
{
if( 0 == root )
return false;
if( root->data > *word )
{
return Search( root->leftChild, word );
}
else if( root->data < *word )
{
return Search( root->rightChild, word );
}
else
{
if( *(word + 1) == '\0' )
{
return true;
}
else
{
return Search( root->midChild, word + 1 );
}
}
}
/*
* Implement insert operation
*
*/
void Insert( pTernaryNode& root, const char* word )
{
if( 0 == root )
{
root = new TernaryNode( *word );
if( *(word + 1) == '\0' )
{
m_size++;
root->isLeaf = 1;
return;
}
else if( root->data < *(word + 1) )
{
Insert( root->rightChild, word + 1 );
}
else if( root->data > *( word + 1) )
{
Insert( root->leftChild, word + 1 );
}
else
{
Insert( root->midChild, word + 1 );
}
}
if( root->data > *word )
{
Insert( root->leftChild, word );
}
else if( root->data < *word )
{
Insert( root->rightChild, word );
}
else
{
if( *(word + 1) == '\0' )
{
root->isLeaf = 1;
}
else
{
Insert( root->midChild, word + 1 );
}
}
}
/*
*
*
*/
void Clear( pTernaryNode& root )
{
if( 0 == root )
{
return;
}
Clear( root->leftChild );
Clear( root->midChild );
Clear( root->rightChild );
delete root;
root = 0;
}
private:
pTernaryNode m_root;
size_t m_size;
};
void TestTernarySearchTree()
{
char* words[] = {"the", "a", "there", "answer", "any", "by", "bye", "their", "ant", "these", "heap",
"dynamic", "day", "micro", "meter", "mimic", "soul","such", "many", "metal",
"year", "deed", "minifest", "theather", "mart", "meet", "mit", "polygon", "pool" };
size_t size = sizeof(words)/sizeof(words[0]);
TernarySearchTree tree;
for( int i = 0; i < size; i++ )
{
tree.Insert( words[i] );
}
for( int i = 0; i < size; i++ )
{
assert( tree.Search( words[i] ) );
}
assert( tree.Search("man") );
assert( tree.Search("mini") );
assert( tree.Search("met") );
assert( tree.Search("so" ) );
assert( !tree.Search("bee"));
assert( !tree.Search("at") );
}
#endif
compile and run in visual studio 2005