我正在尝试从T. H. Cormen实施RB Tree alghoritm,并且无法找到我的问题的解决方案。当我想删除一些节点时,有一个NullPinterException。这是我的代码:
public void rbTreeDelete(RBNode z) {
RBNode y = z;
RBNode x = new RBNode();
Color yOriginalColor = y.color;
if(z.left == null) {
x = z.right;
rbTransplant(z, z.right);
}
else {
if(z.right == null) {
x = z.left;
rbTransplant(z, z.left);
}
else {
y = treeMinimum(z.right);
yOriginalColor = y.color;
x = y.right;
if(y.p == z) {
x.p = y;
}
else {
rbTransplant(y, y.right);
y.right = z.right;
y.right.p = y;
}
rbTransplant(z, y);
y.left = z.left;
y.left.p = y;
y.color = z.color;
}
if(yOriginalColor == Color.Black) {
rbDeleteFixup(x);
}
}
}
public void rbTransplant(RBNode u,RBNode v) {
if(u.p == null) {
root = v;
}
else {
if(u == u.p.left){
u.p.left = v;
}
else {
u.p.right = v;
}
}
if (v != null) {
v.p = u.p;
}
}
public void rbDeleteFixup(RBNode x){
while(x !=root && x.color == Color.Black) {
if(x == x.p.left) {
RBNode w;
w = x.p.right;
if(w.color == Color.Red) {
w.color = Color.Black;
x.p.color = Color.Red;
leftRotate(x.p);
w = x.p.right;
}
if(w.left.color == Color.Black && w.right.color == Color.Black) {
w.color = Color.Red;
x = x.p;
}
else {
if(w.right.color == Color.Black) {
w.left.color = Color.Black;
w.color = Color.Red;
rightRotate(w);
w = x.p.right;
}
w.color = x.p.color;
x.p.color = Color.Black;
w.right.color = Color.Black;
leftRotate(x.p);
x = root;
}
}
else {
RBNode w = x.p.left;
if(w.color == Color.Red) {
w.color = Color.Black;
x.p.color = Color.Red;
rightRotate(x.p);
w = x.p.left;
}
if(w.right.color == Color.Black && w.left.color == Color.Black) {
w.color = Color.Red;
x = x.p;
}
else {
if(w.left.color == Color.Black) {
w.right.color = Color.Black;
w.color = Color.Red;
rightRotate(w);
w = x.p.left;
}
w.color = x.p.color;
x.p.color = Color.Black;
w.left.color = Color.Black;
leftRotate(x.p);
x = root;
}
}
}
x.color = Color.Black;
}
例外情况是:
if(y.p == z) { x.p = y; }
在rbTreeDelete方法中,当我尝试删除具有9值的节点时。我的测试脚本:
t.insert(7);
t.insert(5);
t.insert(8);
t.insert(3);
t.insert(9);
t.insert(18);
t.insert(32);
t.rbTreeDelete(treeSearch(t.root, 32));
t.rbTreeDelete(treeSearch(t.root, 9));
t.rbTreeDelete(treeSearch(t.root, 8));
t.rbTreeDelete(treeSearch(t.root, 5));
t.rbTreeDelete(treeSearch(t.root, 8));
t.rbTreeDelete(treeSearch(t.root, 3));
感谢您的任何建议。
编辑:treeMinimum代码:
public RBNode treeMinimum(RBNode x) {
while(x.left != null){
x = x.left;
}
return x;
}
答案 0 :(得分:0)
所以,我认为问题出在下面的代码中:
这里你将“y”设置为z右边的树最小值(因为z.right!= null),这很好。
但是,这个最小值并不能保证y会有一个正确的节点(y.right!= null)
我相信在尝试分配父节点值之前,由于x被设置为null,您可能会收到空指针。
else {
y = treeMinimum(z.right);
yOriginalColor = y.color;
x = y.right;
if(y.p == z) {
x.p = y;
}