zoukankan      html  css  js  c++  java
  • 数学基础:四、树的应用2(利用树结构存储字典表&深度优先搜索)(优化后:由数组改为Map)

    直接上代码:

    public class Lesson12_1 {
    
        /**
         * @Description: 前缀树的结点
         */
        class TreeNode {
    
            public char label;  // 结点的名称,在前缀树里是单个字母
            public HashMap<Character, TreeNode> sons = null; // 使用哈希映射存放子结点。哈希便于确认是否已经添加过某个字母对应的结点。
            public String prefix = null;   // 从树的根到当前结点这条通路上,全部字母所组成的前缀。例如通路b->o->y,对于字母o结点而言,前缀是b;对于字母y结点而言,前缀是bo
            public String explanation = null;  // 词条的解释
    
            // 初始化结点
            public TreeNode(char l, String pre, String exp) {
                label = l;
                prefix = pre;
                explanation = exp;
                sons = new HashMap<>();
            }
    
            private TreeNode build(String str, String exp, String pre, TreeNode root) {
                if ("".equals(str)) {
                    this.explanation = exp;
                    return root;
                }
                // 处理当前字符串的第一个字母
                char c = str.toCharArray()[0];
                TreeNode found = null;
    
                // 如果字母结点已经存在于当前父结点之下,找出它。否则就新生成一个
                if (this.sons.containsKey(c)) {
                    found = this.sons.get(c);
                } else {
                    TreeNode son = new TreeNode(c, pre, "");
                    this.sons.put(c, son);
                    found = son;
                }
    
                return found.build(str.substring(1), exp, pre + str.substring(0, 1), root);
            }
    
            public TreeNode build(String str, String exp) {
                return this.build(str, exp, "", this);
            }
    
            public String search(String str) {
                if ("".equals(str)) {
                    return "请输入非空字符";
                }
    
                TreeNode found = this;
                char[] chars = str.toCharArray();
                for (char c : chars) {
                    if (!found.sons.containsKey(c)) {
                        return "未查到";
                    } else {
                        found = found.sons.get(c);
                    }
                }
    
                return "".equals(found.explanation) ? "未查到" : found.explanation;
            }
        }
    
        // 使用栈来实现深度优先搜索
        public void dfsByStack(TreeNode root) {
    
            Stack<TreeNode> stack = new Stack<>();
            // 创建堆栈对象,其中每个元素都是TreeNode类型
            stack.push(root);    // 初始化的时候,压入根结点
    
            while (!stack.isEmpty()) {  // 只要栈里还有结点,就继续下去
    
                TreeNode node = stack.pop();  // 弹出栈顶的结点
    
                if (node.sons.size() == 0) {
                    // 已经到达叶子结点了,输出
                    System.out.println(node.prefix + node.label);
                } else {
                    // 非叶子结点,遍历它的每个子结点
                    node.sons.forEach((key, value) -> stack.push(value));
                }
            }
    
        }
    
        @Test
        public void test() {
            TreeNode treeNode = new TreeNode((char) 0, "", "");
            treeNode.build("hello", "你好")
                    .build("world", "世界")
                    .build("helloworld", "你好世界")
                    .build("able", "有能力的")
                    .build("about", "大约")
                    .build("above", "在上面")
                    .build("abroad", "到国外")
                    .build("active", "积极的")
                    .build("activity", "活动");
            System.out.println("构建词库结束,准备查找");
    
            System.out.println(treeNode.search("hello"));
            System.out.println(treeNode.search("world"));
            System.out.println(treeNode.search("helloworld"));
    
            System.out.println(treeNode.search("hell"));
            System.out.println(treeNode.search("helo"));
            System.out.println(treeNode.search("worlda"));
    
            System.out.println("查找结束,准备深度优先搜索");
            dfsByStack(treeNode);
        }
    }
    
  • 相关阅读:
    剑指offer JZ-1
    侯捷《C++面向对象开发》--String类的实现
    侯捷《C++面向对象开发》--复数类的实现
    辛普森悖论
    马尔可夫链的平稳分布
    熵和基尼指数的一些性质
    UVA 11624 Fire!(广度优先搜索)
    HDU 4578 Transformation (线段树区间多种更新)
    HDU 1540 Tunnel Warfare(线段树+区间合并)
    多重背包
  • 原文地址:https://www.cnblogs.com/dulinan/p/12032995.html
Copyright © 2011-2022 走看看