📜  三元搜索树

📅  最后修改于: 2021-04-17 12:04:13             🧑  作者: Mango

三元搜索树是一种特殊的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/三元搜索树