前缀树(又称字典树、单词查找树、Trie树),是一种树形结构,是一种哈希树的变种。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计。它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高。
/* 这个结构的逻辑是字母写在两个节点之间。根节点为root,root.nexts[index] 为与根节点相连的其他节点,把字母想象成两个节点之间路径上的值,靠下的节点 用于存放这个字母的path和end */ public class TrieTree { public static class TrieNode{ public int path; public int end; public TrieNode[] nexts; public TrieNode(){ path = 0; end = 0; nexts = new TrieNode[26]; } } public static class Trie{ private TrieNode root; public Trie(){ root = new TrieNode(); } public void insert(String word){ if(word == null) return; char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for(int i = 0; i < chs.length; i++){ index = chs[i] - 'a'; //如果当前节点没有走向这个字母节点的路径,则创建 if(node.nexts[index] == null){ node.nexts[index] = new TrieNode(); } node = node.nexts[index]; node.path++; } node.end++; //只有字符串最后一个节点的位置end++ } //查某一个word在其中出现了几次,和insert差不多 public int search(String word){ if(word == null) return 0; char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for(int i = 0; i < chs.length; i++){ index = chs[i] - 'a'; if(node.nexts[index] == null) return 0; node = node.nexts[index]; } return node.end; } public void delete(String word){ if(search(word) != 0){ char[] chs = word.toCharArray(); TrieNode node = root; int index = 0; for(int i = 0; i < chs.length; i++){ index = chs[i] - 'a'; //如果这个节点的--path已经为0,则不用管这个节点 //下面的节点,直接return if(--node.nexts[index].path == 0){ node.nexts[index] = null; return; } node = node.nexts[index]; } node.end --; } } public int preFixNum(String pre){ //返回以pre为前缀的单词的个数 if(pre == null){ return 0; } char[] chs = pre.toCharArray(); TrieNode node = root; int index = 0; for(int i = 0; i < chs.length; i++){ index = chs[i] - 'a'; if(node.nexts[index].path == 0) return 0; node = node.nexts[index]; } return node.path; } } }