三元搜索树是一种特殊的trie数据结构,其中标准trie的子节点被排序为二进制搜索树。
三元搜索树的表示形式:
与trie(标准)数据结构中每个节点包含26个用于其子节点的指针不同,三元搜索树中的每个节点仅包含3个指针:
1.左指针指向其值小于当前节点中的值的节点。
2.相等的指针指向其值等于当前节点中的值的节点。
3.右指针指向其值大于当前节点中的值的节点。
除了上述三个指针之外,每个节点还具有一个用于指示数据的字段(在字典的情况下为字符)和另一个用于标记字符串结尾的字段。
因此,它或多或少类似于基于某种顺序存储数据的BST。但是,三元搜索树中的数据分布在节点上。例如,它需要4个节点来存储单词“ Geek”。
下图显示了三元搜索树中的单词是如何存储的?
与尝试相比,使用三元搜索树的优点之一是三元搜索树具有更高的空间利用率(与标准尝试中的26个相比,每个节点仅涉及三个指针)。此外,三元搜索树可以在哈希表用于存储字符串的任何时间使用。
当单词在字母表上适当分布时,尝试尝试是合适的,这样可以最有效地利用空格。否则,三元搜索树更好。当要存储的字符串共享一个公共前缀时,三元搜索树可以高效地使用(就空间而言)。
三元搜索树的应用:
1.三元搜索树对于诸如“给出一个单词,在字典中查找下一个单词(近邻查找)”或“查找所有以9342开头的电话号码,或”在网络浏览器中键入几个起始字符来显示所有网站”之类的查询非常有效。带有此前缀的名称“((自动完成功能)”)。
2.用于拼写检查:三元搜索树可用作存储所有单词的字典。在编辑器中键入单词后,可以在三元搜索树中并行搜索单词以检查拼写是否正确。
执行:
以下是三元搜索树的C实现。实现的操作是搜索,插入和遍历。
// C program to demonstrate Ternary Search Tree (TST) insert, travese
// and search operations
#include
#include
#define MAX 50
// A node of ternary search tree
struct Node
{
char data;
// True if this character is last character of one of the words
unsigned isEndOfString: 1;
struct Node *left, *eq, *right;
};
// A utility function to create a new ternary search tree node
struct Node* newNode(char data)
{
struct Node* temp = (struct Node*) malloc(sizeof( struct Node ));
temp->data = data;
temp->isEndOfString = 0;
temp->left = temp->eq = temp->right = NULL;
return temp;
}
// Function to insert a new word in a Ternary Search Tree
void insert(struct Node** root, char *word)
{
// Base Case: Tree is empty
if (!(*root))
*root = newNode(*word);
// If current character of word is smaller than root's character,
// then insert this word in left subtree of root
if ((*word) < (*root)->data)
insert(&( (*root)->left ), word);
// If current character of word is greate than root's character,
// then insert this word in right subtree of root
else if ((*word) > (*root)->data)
insert(&( (*root)->right ), word);
// If current character of word is same as root's character,
else
{
if (*(word+1))
insert(&( (*root)->eq ), word+1);
// the last character of the word
else
(*root)->isEndOfString = 1;
}
}
// A recursive function to traverse Ternary Search Tree
void traverseTSTUtil(struct Node* root, char* buffer, int depth)
{
if (root)
{
// First traverse the left subtree
traverseTSTUtil(root->left, buffer, depth);
// Store the character of this node
buffer[depth] = root->data;
if (root->isEndOfString)
{
buffer[depth+1] = '\0';
printf( "%s\n", buffer);
}
// Traverse the subtree using equal pointer (middle subtree)
traverseTSTUtil(root->eq, buffer, depth + 1);
// Finally Traverse the right subtree
traverseTSTUtil(root->right, buffer, depth);
}
}
// The main function to traverse a Ternary Search Tree.
// It mainly uses traverseTSTUtil()
void traverseTST(struct Node* root)
{
char buffer[MAX];
traverseTSTUtil(root, buffer, 0);
}
// Function to search a given word in TST
int searchTST(struct Node *root, char *word)
{
if (!root)
return 0;
if (*word < (root)->data)
return searchTST(root->left, word);
else if (*word > (root)->data)
return searchTST(root->right, word);
else
{
if (*(word+1) == '\0')
return root->isEndOfString;
return searchTST(root->eq, word+1);
}
}
// Driver program to test above functions
int main()
{
struct Node *root = NULL;
insert(&root, "cat");
insert(&root, "cats");
insert(&root, "up");
insert(&root, "bug");
printf("Following is traversal of ternary search tree\n");
traverseTST(root);
printf("\nFollowing are search results for cats, bu and cat respectively\n");
searchTST(root, "cats")? printf("Found\n"): printf("Not Found\n");
searchTST(root, "bu")? printf("Found\n"): printf("Not Found\n");
searchTST(root, "cat")? printf("Found\n"): printf("Not Found\n");
return 0;
}
输出:
Following is traversal of ternary search tree
bug
cat
cats
up
Following are search results for cats, bu and cat respectively
Found
Not Found
Found
时间复杂度:三元搜索树操作的时间复杂度与二进制搜索树的时间复杂度相似。也就是说,插入,删除和搜索操作所花费的时间与三元搜索树的高度成比例。该空间与要存储的字符串的长度成正比。
参考:
http://en.wikipedia.org/wiki/三元搜索树