算法22-基于单词查找树的符号表、三向单词查找树(TST)

读者盆友,早上好!
这里介绍下单词查找树、三向单词查找树,后一种都是对前一种的优化,当然各自有各自的适用场景。

本博客代码示例均来自:算法 Algorithmes Forth Edition
[美] Robert Sedgewick Kevin Wayne 著 谢路云译

一、基于单词查找树的符号表

package com.cmh.algorithm.str;

/**
 * 基于单词查找树的符号表
 * Author:起舞的日子
 * Date:  2020/4/29 08:21
 */
public class TriesST<Value> {
    /**
     * 这是一种新的以字符串为结点的树结构
     * 树结构最大的优点是:
     * 既有利于快速查找
     * 也有利于快速插入(优化到极致)
     */

    /**
     * 基数
     */
    private static int R = 256;

    /**
     * 单词查找树的根结点
     */
    private Node root;

    private static class Node {
        private Object val;
        private Node[] next = new Node[R];
    }

    public Value get(String key) {
        Node x = get(root, key, 0);
        if (x == null) {
            return null;
        }
        return (Value) x.val;
    }

    private Node get(Node x, String key, int d) {
        //返回以x作为根结点的子单词查找树中与key相关联的值
        if (x == null) {
            return null;
        }
        if (d == key.length()) {
            return x;
        }
        //找到第d个字符所对应的子单词查找树
        char c = key.charAt(d);
        return get(x.next[c], key, d + 1);
    }

    public void put(String key, Value val) {

    }

    private Node put(Node x, String key, Value val, int d) {
        //如果key存在于以x为根结点的子单词查找树中则更新与它相关的值
        if (x == null) {
            x = new Node();
        }
        if (d == key.length()) {
            x.val = val;
            return x;
        }
        //找到第d个字符所对应的子单词查找树
        char c = key.charAt(d);
        x.next[c] = put(x.next[c], key, val, d + 1);
        return x;
    }

    /**
     * 总结
     * 缺点:极端情况单向分支很长,"长长的尾巴"(大量长键导致)
     */
}

二、三向单词查找树(TST)

package com.cmh.algorithm.str;

/**
 * 基于三向单词查找树的符号表
 * Author:起舞的日子
 * Date:  2020/4/29 08:34
 */
public class TST<Value> {
    private Node root;

    private class Node {
        /**
         * 字符
         */
        char c;
        /**
         * 左中右子三向单词查找树
         */
        Node left, mid, right;

        /**
         * 和字符串相关联的值
         */
        Value val;
    }

    public Value get(String key) {
        TST.Node x = get(root, key, 0);
        if (x == null) {
            return null;
        }
        return (Value) x.val;
    }

    private Node get(Node x, String key, int d) {
        if (x == null) {
            return null;
        }
        char c = key.charAt(d);
        if (c < x.c) {
            return get(x.left, key, d);
        } else if (c > x.c) {
            return get(x.right, key, d);
        } else if (d < key.length() - 1) {
            return get(x.mid, key, d + 1);
        } else {
            return x;
        }
    }

    public void put(String key, Value val) {
        root = put(root, key, val, 0);
    }

    private Node put(Node x, String key, Value val, int d) {
        char c = key.charAt(d);
        if (x == null) {
            x = new Node();
            x.c = c;
        }
        if (c < x.c) {
            x.left = put(x.left, key, val, d);
        } else if (c > x.c) {
            x.right = put(x.right, key, val, d);
        } else if (d < key.length() - 1) {
            x.mid = put(x.mid, key, val, d + 1);
        } else {
            x.val = val;
        }
        return x;
    }

    /**
     * 总结:
     * 1、每个结点只含有三个链接,所需空间远小于单词查找树
     * 2、适用于非随机的键
     */
}

三、源码

https://github.com/cmhhcm/my2020.git

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值