【alg4-字符串】三向单词查找树

三向单词查找树

为了避免R向单词查找树过度的空间消耗,可以使用三向单词查找树(TST)。在三向单词查找树中,每个结点都含有一个字符、三条链接和一个值。这三条链接分别对应着当前字母小于、等于和大于结点字母的所有键。在R向单词查找树中,树的结点含有R条链接,每个非空链接的索引隐式地表示了它所对应的字符。在等价的三向单词查找树中,字符是显式地保存在结点中的——只有在沿着中间链接前进时才会根据字符找到表中的键。

查找与插入操作

在查找时,首先比较键的首字母和根结点的字母。如果键的首字母较小,就选择左链接;如果较大,就选择右链接;如果相等,则选择中链接。然后,递归地使用相同的算法。如果遇到了一个空链接或者当键结束时结点的值为空,那么查找未命中;如果键结束时结点的值非空则查找命中。在插入新键时,首先进行查找,然后和在单词查找树一样,在树中补全键末尾的所有结点。

性质

空间

三向单词查找树最重要的性质就是每个结点只含有三个链接,因此三向单词查找树所需要空间远小于对应的单词查找树。
由N个平均长度为w的字符串构造的三向单词查找树中的链接总数在3N到3Nw之间。

查找成本

在一棵由N个随机字符串构造的三向单词查找树中,查找未命中平均需要比较字符~lnN次。除~lnN次外,一次插入或命中的查找会比较一次被查找的键中的每个字符。

代码

package section5_2;

public class TST<Value> {

    private Node root;
    private class Node {
        char c;
        Node left,mid,right;
        Value val;
    }

    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) {
        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;
    }

    public static void main(String[] args) {
        String[] a = {
                "she",
                "sells",
                "sea",
                "shells",
                "by",
                "the",
                "shore"
        };
        TST<Integer> tst = new TST<>();
        for (int i = 0;i < a.length;i++) {
            tst.put(a[i],i);
        }
        System.out.println("test get:");
        System.out.println(tst.get("shells"));
        System.out.println(tst.get("shell"));

    }

}

输出:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值