• 原创:自定义三叉树


    package com.txq.ternaryTree;


    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.UnsupportedEncodingException;
    import java.util.HashSet;
    import java.util.Set;
    /**
    * 自定义三叉树
    * @author TongXueQiang
    * @date 2016/03/03
    * @since JDK 1.7
    */
    public class TernaryTree {
    // 根节点
    private static Node root;
    // 存储前缀匹配结果的集合
    private Set<String> result = new HashSet<String>();

    /**
    * 向树中插入字符
    *
    * @param node
    * @param word
    * @return
    */
    public void insert(String word) {
    root = insert(root, word, 0);
    }

    /**
    * 插入字符具体实现
    *
    * @param node
    * @param word
    * @param index
    * @return
    */
    private Node insert(Node node, String word, int index) {
    if (word == null || word.equals("")) {
    return null;
    }
    char[] charArray = word.toCharArray();

    // 如果节点为空,创建新的节点
    if (node == null) {
    node = new Node(charArray[index], false);
    }
    // 如果当前字符小于当前节点存储的字符,插入左节点的位置
    if (charArray[index] < node.storedChar) {
    node.leftNode = insert(node.leftNode, word, index);
    }
    // 如果当前字符大于当前节点存储的字符,插入右节点的位置
    else if (charArray[index] > node.storedChar) {
    node.rightNode = insert(node.rightNode, word, index);
    } else {// 相等
    // 递归终止条件
    if (index == charArray.length - 1) {
    node.isCompleted = true;
    } else {
    node.centerNode = insert(node.centerNode, word, ++index);
    }
    }

    return node;
    }

    /**
    * 查找以指定前缀开头的所有字符串
    *
    * @param prefix
    * @return
    */
    public Set<String> searchPrefix(String prefix) {
    // 首先查找前缀的下一个centerNode
    Node node = findNode(prefix);
    return searchPrefix(node, prefix);
    }

    /**
    * 查找以指定前缀开头的所有字符串的具体实现
    *
    * @param node
    * @param prefix
    * @return
    */
    private Set<String> searchPrefix(Node node, String prefix) {
    if (node != null) {//递归终止条件
    //如果是成词,加入到结果集中
    if (node.isCompleted) {
    result.add(prefix + node.storedChar);
    }

    searchPrefix(node.leftNode,prefix);//向左查找
    searchPrefix(node.centerNode,prefix + node.storedChar);//向中间查找
    searchPrefix(node.rightNode,prefix);//向右查找
    }

    //如果前缀是成词
    if (isWord(prefix))
    result.add(prefix);

    return result;
    }
    /**
    * 判断前缀是否为成词
    * @param prefix
    */
    private boolean isWord(String prefix) {
    return isWord(root,prefix,0);
    }

    private boolean isWord(Node node, String prefix, int index) {
    if (node == null) {
    return false;
    }

    char[] charArray = prefix.toCharArray();
    // 如果当前字符小于当前节点存储的字符,查找左节点
    if (charArray[index] < node.storedChar) {
    return isWord(node.leftNode, prefix, index);
    }
    // 如果当前字符大于当前节点存储的字符,查找右节点
    else if (charArray[index] > node.storedChar) {
    return isWord(node.rightNode, prefix, index);
    } else {// 相等
    // 递归终止条件
    if (index == charArray.length - 1) {
    if (node.isCompleted ) {
    return true;
    }
    return false;
    }
    else {
    return isWord(node.centerNode, prefix, ++index);
    }

    }
    }

    /**
    * 查找前缀的下一个centerNode,作为searchPrefix的开始节点
    *
    * @param prefix
    * @return
    */
    private Node findNode(String prefix) {
    return findNode(root, prefix, 0);
    }

    private Node findNode(Node node, String prefix, int index) {
    if (prefix == null || prefix.equals("")) {
    return null;
    }
    if (node == null) {
    return null;
    }
    char[] charArray = prefix.toCharArray();
    // 如果当前字符小于当前节点存储的字符,查找左节点
    if (charArray[index] < node.storedChar) {
    return findNode(node.leftNode, prefix, index);
    }
    // 如果当前字符大于当前节点存储的字符,查找右节点
    else if (charArray[index] > node.storedChar) {
    return findNode(node.rightNode, prefix, index);
    } else {// 相等
    // 递归终止条件
    if (index == charArray.length - 1) {
    return node.centerNode;
    }
    else {
    return findNode(node.centerNode, prefix, ++index);
    }
    }
    }

    /**
    * 加载主字典
    */


    public void loadDict() {
    InputStream is = super.getClass().getClassLoader().getResourceAsStream("com/txq/ternaryTree/word.dic");
    if (is == null) {
    throw new RuntimeException("Main Dictionary not found!!!");
    }
    try {
    BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8"),512);
    String newWord = null;
    do {
    newWord = br.readLine();
    if (newWord != null && !"".equals(newWord.trim())) {
    this.insert(newWord);
    }
    }while(newWord != null);
    }catch(Exception e){
    e.printStackTrace();
    }
    finally{
    try {
    if (is != null) {
    is.close();
    is = null;
    }
    } catch(Exception e){
    e.printStackTrace();
    }
    }
    }
    }

    以下是测试类:

    package com.txq.ternaryTree;

    import java.util.Set;

    public class Test {

    public static void main(String[] args) {
    // String originalWord = "acfbedg";
    // String result = QuickSortAndCompromise.sortAndCompromise(originalWord, new StringBuffer());
    // System.out.println(result);

    TernaryTree t = new TernaryTree();
    t.loadDict();

    Set<String> result = t.searchPrefix("中华");
    System.out.println(result);
    }

    }

  • 相关阅读:
    [LeetCode] Bulb Switcher II 灯泡开关之二
    [LeetCode] Second Minimum Node In a Binary Tree 二叉树中第二小的结点
    [LeetCode] 670. Maximum Swap 最大置换
    [LeetCode] Trim a Binary Search Tree 修剪一棵二叉搜索树
    [LeetCode] Beautiful Arrangement II 优美排列之二
    [LeetCode] Path Sum IV 二叉树的路径和之四
    [LeetCode] Non-decreasing Array 非递减数列
    [LeetCode] 663. Equal Tree Partition 划分等价树
    [LeetCode] 662. Maximum Width of Binary Tree 二叉树的最大宽度
    [LeetCode] Image Smoother 图片平滑器
  • 原文地址:https://www.cnblogs.com/txq157/p/5239928.html
Copyright © 2020-2023  润新知