shz.core.st.tst.TST Maven / Gradle / Ivy
package shz.core.st.tst;
import shz.core.queue.a.CArrayQueue;
import shz.core.queue.a.LArrayQueue;
import java.io.Serializable;
import java.util.function.Predicate;
/**
* 基于三向单词查找树的符号表
*
* 由N个平均长度为w的字符串构造的三向单词查找树中的链接总数在3N到3Nw之间
*
* 在一棵由N个随机字符串构造的三向单词查找树中,查找未命中平均需要比较字符~lnN次。除~lnN次外,一次插入或命中的查找会比较一次被查找的键中的每个字符
*/
public abstract class TST> implements Serializable {
private static final long serialVersionUID = 2787123954223919870L;
protected static abstract class Node> implements Serializable {
private static final long serialVersionUID = -6194352568723912441L;
public char c;
public T left, mid, right;
public boolean leaf;
protected Node(char c) {
this.c = c;
}
}
protected T root;
private T get(T x, char[] a, int d, int n) {
if (x == null) return null;
if (a[d] < x.c) return get(x.left, a, d, n);
if (a[d] > x.c) return get(x.right, a, d, n);
if (d < n) return get(x.mid, a, d + 1, n);
return x;
}
protected final T get(T x, char[] a, int n) {
return get(x, a, 0, n - 1);
}
public final void delete(char[] a) {
T p = get(root, a, 0, a.length - 2);
if (p == null) return;
if (p.left != null && p.left.c == a[a.length - 1]) {
p.left.leaf = false;
if (p.left.left == null && p.left.mid == null && p.left.right == null) p.left = null;
} else if (p.mid != null && p.mid.c == a[a.length - 1]) {
p.mid.leaf = false;
if (p.mid.left == null && p.mid.mid == null && p.mid.right == null) p.mid = null;
} else if (p.right != null && p.right.c == a[a.length - 1]) {
p.right.leaf = false;
if (p.right.left == null && p.right.mid == null && p.right.right == null) p.right = null;
}
}
protected final LArrayQueue getChars0(Predicate predicate, int limit) {
LArrayQueue result = LArrayQueue.of();
CArrayQueue key = CArrayQueue.of();
getChars0(result, key, root, predicate, limit);
return result;
}
private void getChars0(LArrayQueue result, CArrayQueue key, T x, Predicate predicate, int limit) {
if (x == null || (limit > 0 && result.size() >= limit)) return;
if (x.leaf && predicate.test(x)) {
char[] chars = new char[key.size() + 1];
System.arraycopy(key.toArray(), 0, chars, 0, key.size());
chars[key.size()] = x.c;
result.offer(chars);
}
if (x.left != null) getChars0(result, key, x.left, predicate, limit);
if (x.mid != null) {
key.offer(x.c);
getChars0(result, key, x.mid, predicate, limit);
key.removeTail();
}
if (x.right != null) getChars0(result, key, x.right, predicate, limit);
}
}