Data Structure: Trie(字典树)

来源:互联网 发布:迅雷下载mac版 编辑:程序博客网 时间:2024/06/06 02:54

字典树是一个用数组(数组代表子节点数目是静态的)来表示子节点的树结构。同时节点也需要域:boolean isEnd。 


本文章参考:https://leetcode.com/problems/implement-trie-prefix-tree/solution/


Trie的一些应用:1)Autocomplete; 2) Spell checker; 3) IP routing.

首先,列出TrieNode的实现:


每个Node都必须有maxEnum个子节点。(数组长度固定为key的字母可能数)。譬如,如果key只限26个小写字母,那么maxEnum = 26. 


接着,就是一些常用的getter和setter了。代码如下:


class TrieNode {    // R links to node children    private TrieNode[] links;    private final int R = 26;    private boolean isEnd;    public TrieNode() {        links = new TrieNode[R];    }    public boolean containsKey(char ch) {        return links[ch -'a'] != null;    }    public TrieNode get(char ch) {        return links[ch -'a'];    }    public void put(char ch, TrieNode node) {        links[ch -'a'] = node;    }    public void setEnd() {        isEnd = true;    }    public boolean isEnd() {        return isEnd;    }}


实现Trie的insert,inser在每次迭代当中有两种可能:


1)当前搜索的子节点当中,没有当前的字母,初始化该索引的node;

2)存在当前字母的node,接着搜索其子节点或者当前已经是key的最后一个字母了,完成,记得setEnd(),标记一下当前的node。


class Trie {    private TrieNode root;    public Trie() {        root = new TrieNode();    }    // Inserts a word into the trie.    public void insert(String word) {        TrieNode node = root;        for (int i = 0; i < word.length(); i++) {            char currentChar = word.charAt(i);            if (!node.containsKey(currentChar)) {                node.put(currentChar, new TrieNode());            }            node = node.get(currentChar);        }        node.setEnd();    }}

实现Trie的Search,Search存在几种可能:


1)搜到当前节点是isEnd()且也是key的最后一个字母,返回true;

2)搜到当前节点不是isEnd()且是key的最后一个字母,返回false;

3)搜到null了,不论是不是key的最后一个字母,返回false。


代码如下:


class Trie {    ...    // search a prefix or whole key in trie and    // returns the node where search ends    private TrieNode searchPrefix(String word) {        TrieNode node = root;        for (int i = 0; i < word.length(); i++) {           char curLetter = word.charAt(i);           if (node.containsKey(curLetter)) {               node = node.get(curLetter);           } else {               return null;           }        }        return node;    }    // Returns if the word is in the trie.    public boolean search(String word) {       TrieNode node = searchPrefix(word);       return node != null && node.isEnd();    }}


利用上述的代码,很容易就可以实现startWith():


class Trie {    ...    // search a prefix or whole key in trie and    // returns the node where search ends    private TrieNode searchPrefix(String word) {        TrieNode node = root;        for (int i = 0; i < word.length(); i++) {           char curLetter = word.charAt(i);           if (node.containsKey(curLetter)) {               node = node.get(curLetter);           } else {               return null;           }        }        return node;    }    // Returns if the word is in the trie.    public boolean search(String word) {       TrieNode node = searchPrefix(word);       return node != null && node.isEnd();    }}






原创粉丝点击