我想使用三元搜索树中的键删除特定的节点。在大多数情况下,这种方法效果很好,但是在我的一些测试集中,没有中间子级的节点也不会存储值,这是不应该发生的。
我尝试了在网上找到的不同方法,但是几乎所有这些方法都使树处于脏状态,这使查找麻烦,因为您需要检查找到的叶子是否确实具有价值,这不应该不会发生。
这是我的相关代码
private boolean hasChildren(Node x) {
return (x.left != null || x.mid != null || x.right != null);
}
private void reHang(Node x) {
if (hasChildren(x)) {
if (x.left != null) {
x.parent.mid = x.left;
x.left.right = x.right;
} else if (x.right != null) {
x.parent.mid = x.right;
}
}
}
private boolean remove(Node x, String key, int d) {
if (x == null) return false;
char c = key.charAt(d);
if (c < x.c) {
if (!remove(x.left, key, d)) {
x.left = null;
}
} else if (c > x.c) {
if (!remove(x.right, key, d)) {
x.right = null;
}
} else if (d < key.length() - 1) {
if (!remove(x.mid, key, d + 1)) {
x.mid = null;
if (x.val != null) return true;
}
} else {
x.val = null;
}
reHang(x);
return hasChildren(x);
}
private class Node
{
private Value val;
private char c;
private Node left, mid, right, parent;
}
具体来说,我用于前缀查找的此函数中出现问题:
private Node getMidPath(Node x) {
if (x.left != null) return getMidPath(x.left);
if (x.mid == null) return x;
return getMidPath(x.mid);
}
每个没有x.mid的节点都应该设置一个x.val,这在删除后并不总是这样,这意味着我有肮脏的节点。
任何帮助将不胜感激。
答案 0 :(得分:0)
您必须在以下位置看到一棵三叉树:一些嵌套的二叉树,但是每个级别的巫婆都只将字符作为键,而不是整个字符串。遍历您的二叉树,直到字符串用尽。在这里,您将拥有两个最终引用,一个是对实际数据的引用,另外两个是对具有相同前缀的较长字符串的实际子树的引用。现在将数据设置为空。当子树引用为null时,删除该节点。现在,当整个子树为空时,请继续将子树提前一个字符。在这里,将子树引用设置为null。现在两个引用都为空,删除节点。现在,当整个子树为空时,请继续将子树提前一个字符。等等