Java数据结构---Trie(字典树/前缀树)
1. Trie简介
前缀树是一种树形结构,在百度中查找一个单词,通常搜索前几个字母,百度就会自动提示后面的字母,即搜索提示,这是前缀树的一个最典型的应用。
2. 该数据结构的节点的构建
前缀树的结点包含属性isWord和指向孩子节点的指针children,它是一个数组。 完整的定义:
class TrieNode { // 该节点的属性---isWord,它是一个标签,用来表示是否是一个完整的单词 boolean isWord; // 定义该节点的孩子节点,用一个长度为26的TrieNode[]数组来存储指向下一个孩子节点的指针 TrieNode[] children; public TrieNode { // 默认isWord标签为false isWord = false; // 默认孩子节点有26个(英文字母有26个),用一个长度为26的TrieNode[]数组来存储孩子节点的指针 children = new TrieNode[26]; } }
可以简写成如下形式:
class TrieNode { boolean isWord; TrieNode[] children = new TrieNode[26]; }
3. 前缀树的构建
// 定义前缀树的节点 class TrieNode { boolean isWord; TrieNode[] children = new TrieNode[26]; } // 定义前缀树 class Trie { TrieNode root; public Trie() { // 构造一个空的节点作为根节点 root = new TrieNode(); }
4. 基础操作(增、查)
- 增 insert()
public void insert(String word) { TrieNode cur = root; for (int i = 0; i < word.length(); i++) { // c为要保存字符的ASCII码值 int c = word.charAt(i) - a; // 如果当前节点的值为c的孩子节点不存在,则新建该孩子节点并指向它 if (cur.children[c] == null) { cur.children[c] = new TrieNode(); } // 如果当前节点的值为c的孩子节点存在,则cur指向该孩子节点 cur = cur.children[c]; } // 当所有节点都遍历完成,将当前节点,即最后一个节点的标识符isWord置为true,表示从根节点遍历到该节点的字母组成了一个单词 cur.isWord = true; }
- 完整查找 search():给定一个完整的单词,在前缀树中查找它是否存在 思路:如果在遍历过程中发现字母有缺失(cur.children[c] == null),即下一个字母查找为null,则返回false,表示前缀树种不存在这个单词。如果遍历完成,就要判断此时cur是否为单词末尾:如果是,返回true;如果不是,说明word仅仅是一个前缀,并不完整,返回false
public boolean search(String word){ TrieNode cur = root; for(int i = 0;i < word.length(); i++){ int c = word.charAt(i)-a; if(cur.children[c] == null) return false; cur = cur.children[c]; } return cur.isWord; }
- 按前缀查找 startsWith() 思路:与完整查找类似,区别在于不需要判断最后一个节点是否是isWord
public boolean search(String word){ TrieNode cur = root; for(int i = 0;i < word.length(); i++){ int c = word.charAt(i)-a; if(cur.children[c] == null) return false; cur = cur.children[c]; } return true; }