【乱七八糟的笔记】——前缀树

前缀树的构建

  • 利用数组构建
// change this value to adapt to different cases
#define N 26

struct TrieNode {
    TrieNode* children[N];
    
    // you might need some extra values according to different cases
};

/** Usage:
 *  Initialization: TrieNode root = new TrieNode();
 *  Return a specific child node with char c: (root->children)[c - 'a']
 */
class TrieNode{  // 前缀树节点的实现
public:
    TrieNode* children[26]; // 前缀树可以存储26个小写字母,存在next数组中。
    bool flage;
    TrieNode() { // 构造函数
        memset(children, NULL, sizeof(children)); // 分配空间
        flage = false;
    }
    ~TrieNode() { // 析构函数。此处可以不写,实际中写上较好。
        for (int i = 0; i < 26; i++) {
            if(children[i]) delete children[i];
        }
    }
};

  访问子节点更加快捷,且容易,但并非所有子节点都会用到,会造成空间的浪费。

  • 利用哈希表构建
struct TrieNode {
    unordered_map<char, TrieNode*> children;
    
    // you might need some extra values according to different cases
};

/** Usage:
 *  Initialization: TrieNode root = new TrieNode();
 *  Return a specific child node with char c: (root->children)[c]
 */

  访问子节点更加容易,但速度稍慢,但方法较为灵活,不会收到固定长度、范围的限制。

前缀树的插入

Initialize: cur = root
for each char c in target string S:
	if cur does not have a child c:
		cur.children[c] = new Trie node
	cur = cur.children[c]
cur is the node which represents the string S

前缀树的搜索

Initialize: cur = root
for each char c in target string S:
	if cur does not have a child c:
		search fails
	cur = cur.children[c]
search successes

前缀树的实现

struct TrieNode {
    bool flag;
    map<char, TrieNode*> next; 
};
class Trie {
private:
    TrieNode* root;
    
public:
    /** Initialize your data structure here. */
    Trie() {
        root = new TrieNode();
    }
    
    /** Inserts a word into the trie. */
    void insert(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                // insert a new node if the path does not exist
                (p->next).insert(make_pair(word[i], new TrieNode()));
            }
            p = (p->next)[word[i]];
        }
        p->flag = true;
    }
    
    /** Returns if the word is in the trie. */
    bool search(string word) {
        TrieNode* p = root;
        for (int i = 0; i < word.length(); ++i) {
            if ((p->next).count(word[i]) <= 0) {
                return false;
            }
            p = (p->next)[word[i]];
        }
        return p->flag;
    }
    
    /** Returns if there is any word in the trie that starts with the given prefix. */
    bool startsWith(string prefix) {
        TrieNode* p = root;
        for (int i = 0; i < prefix.length(); ++i) {
            if ((p->next).count(prefix[i]) <= 0) {
                return false;
            }
            p = (p->next)[prefix[i]];
        }
        return true;
    }
};

/**
 * Your Trie object will be instantiated and called as such:
 * Trie obj = new Trie();
 * obj.insert(word);
 * bool param_2 = obj.search(word);
 * bool param_3 = obj.startsWith(prefix);
 */
上一篇:ioc+ef+core搭建模型映射(三)


下一篇:MVC5 + EF6 完整入门教程三