字典树

来源:互联网 发布:mac os x 10.11 下载 编辑:程序博客网 时间:2024/06/13 10:28

字典树是哈希树的一种变种。

有如下三个性质:

1.根节点不包含字符,除根节点外每一个节点都只包含一个字符; 

2.从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串; 

3.每个节点的所有子节点包含的字符都不相同。


搜索字典的方法:

(1) 从根结点开始一次搜索;
(2) 取得要查找关键词的第一个字母,并根据该字母选择对应的子树并转到该子树继续进行检索;
(3) 在相应的子树上,取得要查找关键词的第二个字母,并进一步选择对应的子树进行检索。
(4) 迭代过程……
(5) 在某个结点处,关键词的所有字母已被取出,则读取附在该结点上的信息,即完成查找。
/** * 抽象一棵字典树,并且初始化 *  * @author zcsolf * */public class Trie1 {private final int SIZE = 26;private TrieNode root; // 定义一个根节点public Trie1() {root = new TrieNode();}public static void main(String[] args) {// 程序入口:<span style="white-space:pre"></span>根据学习情况进行测试// Trie1 t = new Trie1();// t.Insert("apple");// System.out.println("**********");// t.Insert("apm");// System.out.println("**********");// System.out.println(t.CountPrefix("ap"));}/* * 抽象出树的节点 */class TrieNode {private int num; // 统计有多少单词通过该节点private boolean isEnd; // 标识位,判断是否为最后一个节点private char value; // 该节点的值private TrieNode[] TrieSons; // 节点的所有子节点TrieNode() { // 节点的构造函数num = 1;isEnd = false;TrieSons = new TrieNode[SIZE];}}/** * 向字典树中插入单词的方法 *  * @param word:传入要插入的单词,为String类型 */public void Insert(String word) {// 如果插入单词为空,结束插入if (word == null || "".equals(word.trim())) {return;}TrieNode node = root; // 定义出根节点;char[] letters = word.toCharArray(); // 将word转换为char数组/** * 遍历letters数组,如果 */for (int i = 0; i < word.length(); i++) {int order = letters[i] - 'a'; // 子分支的位置if (node.TrieSons[order] == null) {node.TrieSons[order] = new TrieNode(); // 如果该根节点的子节点中没有该字母,则给其申请一个新的节点空间  将字母的ascii转换成int,-97node.TrieSons[order].value = letters[i]; // 同时,给该节点的值域赋值为该字母.System.out.println(node.TrieSons[order].value);} else {node.TrieSons[order].num++;System.out.println("num:" + node.TrieSons[order].num);}node = node.TrieSons[order];}node.isEnd = true; // 插入完毕}/** * 统计单词前缀的方法 *  * @param prefix:相同的前缀 * @return */public int CountPrefix(String prefix) {if (prefix == null || prefix.length() == 0) {return -1;}TrieNode node = root;char[] letters = prefix.toCharArray();for (int i = 0; i < prefix.length(); i++) {int order = letters[i] - 'a';if (node.TrieSons[order] == null) { // 如果没有该字母的子节点,则表示该字母不是前缀中的字母,返回零return 0;} else {node = node.TrieSons[order];}}return node.num;}/** * 输出前缀的单词 *  * @param prefix * @return */public String hasPrefix(String prefix) {if (prefix == null || prefix.length() == 0) {return null;}TrieNode node = root;char[] letters = prefix.toCharArray();for (int i = 0, len = prefix.length(); i < len; i++) {int pos = letters[i] - 'a';if (node.TrieSons[pos] == null) {return null;} else {node = node.TrieSons[pos];}}preTraverse(node, prefix);return null;}/** * 遍历经过此节点的单词的方法 *  * @param node * @param prefix  用于存储遍历的值 */public void preTraverse(TrieNode node, String prefix) {// TODO Auto-generated method stubif (!node.isEnd) {for (TrieNode child : node.TrieSons) {if (child != null) {preTraverse(child, prefix + child.value); // 递归调用}}return;}System.out.println(prefix);}/** * 在字典树中查找跟word完全匹配的单词 *  * @param word * @return */public boolean Match(String word) {if (word == null || word.length() == 0) {return false;}TrieNode node = root;char[] letters = word.toCharArray();for (int i = 0, len = word.length(); i < len; i++) {int pos = letters[i] - 'a';if (node.TrieSons[pos] != null) {node = node.TrieSons[pos];} else {return false;}}return node.isEnd;}/** * 前序遍历字典树 *  * @param node */public void preTraverse(TrieNode node) {if (node != null) {System.out.print(node.value + "-");for (TrieNode child : node.TrieSons) {<span style="white-space:pre"></span>//迭代过程preTraverse(child);}}}public TrieNode getRoot() {return this.root;}}

0 0
原创粉丝点击