读者盆友,早上好!
这里介绍下单词查找树、三向单词查找树,后一种都是对前一种的优化,当然各自有各自的适用场景。
本博客代码示例均来自:算法 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