LeetCode算法学习---Trie(前缀树)

Trie (发音为 "try") 或前缀树是一种树数据结构,用于检索字符串数据集中的键。这一高效的数据结构有多种应用:1. 自动补全 2.拼写检查 3.九宫格打字预测 4.IP路由(最长前缀匹配)

为什么需要Trie树结构?

哈希表可以在 O(1)O(1) 时间内寻找键值,却无法高效的完成以下操作:

  • 找到具有同一前缀的全部键值。
  • 按词典序枚举字符串的数据集。


Trie 树优于哈希表的另一个理由是,随着哈希表大小增加,会出现大量的冲突,时间复杂度可能增加到 O(n),其中 n是插入的键的数量。与哈希表相比,Trie 树在存储多个具有相同前缀的键时可以使用较少的空间。此时 Trie 树只需要 O(m)的时间复杂度,其中 m 为键长。而在平衡树中查找键值需要 O(mlogn) 时间复杂度。

Trie 树的结点结构
Trie 树是一个有根的树,其结点具有以下字段:

  1. 最多 R 个指向子结点的链接,其中每个链接对应字母表数据集中的一个字母。本文中假定 R 为 26,小写拉丁字母的数量。
  2. 布尔字段,以指定节点是对应键的结尾还是只是键前缀。

结构体如下:

struct TrieNode {
    bool isEnd; //该结点是否是一个串的结束
    TrieNode* next[26]; //字母映射表
};

初始化

 Trie() {
        for(int i=0;i<26;i++){
            root->nodes[i] = NULL;
        }
        root->isEnd = true;
}

插入

void insert(string word) {
        TrieNode * now  = root;
        for(char c : word){
            if(now->nodes[c-'a'] == NULL){
                now->nodes[c-'a'] = new TrieNode();
            }

            now= now->nodes[c-'a'];
        }
        now->isEnd =  true;
}

查找

bool search(string word) {
        TrieNode * now = root;
        for(char c : word){
            if(now->nodes[c-'a'] == NULL){
                return false;
            }
            now = now->nodes[c-'a'];
        }

        if(now->isEnd) return true;
        else return false;
}

 

判断前缀

bool startsWith(string prefix) {
        TrieNode * now = root;
        for(char c:prefix){
            if(now->nodes[c-'a'] == NULL)
                return false;
            now = now->nodes[c-'a'];
        }
        return true;
}

 

参考自leetcode208题 实现Trie树 题目链接 https://leetcode-cn.com/problems/implement-trie-prefix-tree/

前缀树的应用:对字典实现单词搜索 https://leetcode-cn.com/problems/word-search-ii/

 

你可能感兴趣的:(算法,C++,leetcode,字符串,数据结构,算法)