Trie树(字典树、前缀树)

简介

Trie树:又称单词查找树,字典树,是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。

基本性质

  1. 根节点不包含字符,除根节点以外每个节点只包含一个字符。
  2. 从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。
  3. 每个节点的所有子节点包含的字符串不相同。

数据结构

class Trie {
private:
    Trie *nxt[26]; // 26叉树
    bool isEnd; //判断该字符是否为单词的末尾
};

基本函数

  1. void insert(string word): 将字符串word插入到 Trie 树中。其实就是将字符转化为 26 26 26(只包含大写或小写字母)个数字,然后以指针的形式进行遍历和判断,首先建立一个根节点不存储数据,然后每次遍历插入的字符串,如果该字符串中的单词在 Trie 树中,那么 root 节点就会移动到当前字符所指的 next 节点;否则就创建一个新节点来保存next节点,更新root节点,直到遍历完毕后,给这个单词进行标记,即 isEnd = true;
  2. bool search(string word): 判断 word字符串是否存在于 Trie 树中。遍历该字符串,如果当前字符串的next节点为空,说明该字符下面没有接任何的字符,返回 false;否则继续,直到全部遍历完毕,判断末尾字符的isEnd是否为true即可。
  3. bool startsWith(string prefix): 判断 prefix 是否为前缀。跟 search 操作类似,只不过不需要判断prefix 的结尾是否为单词而已。

例题 leetcode 208. 实现 Trie (前缀树)

实现一个 Trie (前缀树),包含 insert, search, 和 startsWith 这三个操作。

示例:

Trie trie = new Trie();

trie.insert("apple");
trie.search("apple");   // 返回 true
trie.search("app");     // 返回 false
trie.startsWith("app"); // 返回 true
trie.insert("app");   
trie.search("app");     // 返回 true

代码实现

class Trie {
private:
    Trie *nxt[26];
    bool isEnd;
public:
    /** Initialize your data structure here. */
    Trie() {
        for(int i=0; i<26; i++) nxt[i] = nullptr;
        isEnd = false;
    }

    /** Inserts a word into the trie. */
    void insert(string word) {
        Trie* root = this;
        for(auto ch : word) {
            int id = ch - 'a';
            if(root->nxt[id] == NULL) root->nxt[id] = new Trie();
            root = root->nxt[id];
        }
        root->isEnd = true;
    }

    /** Returns if the word is in the trie. */
    bool search(string word) {
        Trie* root = this;
        for(auto ch : word) {
            int id = ch - 'a';
            if(root->nxt[id] == NULL) return false;
            root = root->nxt[id];
        }
        return root->isEnd;
    }

    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        Trie* root = this;
        for(auto ch : prefix) {
            int id = ch - 'a';
            if(root->nxt[id] == NULL) return false;
            root = root->nxt[id];
        }
        return true;
    }
};

你可能感兴趣的:(LeetCode)