【发布时间】:2020-12-02 17:49:00
【问题描述】:
因此,我正在尝试使用“算法简介”中所述的哨兵来实现红黑树的插入。
我为一个红黑节点创建了一个通用类,它的数据属性为类型参数,其他属性为:父(节点类型)、左子(节点类型)、右子(节点类型)和颜色(具有红色和黑色值的枚举类型)。
红背节点类:-
public class RedBlackTreeNode<T extends Comparable<T>> {
enum color{
RED,
BLACK
}
private T data;
private color color;
private RedBlackTreeNode<T> leftChild;
private RedBlackTreeNode<T> rightChild;
private RedBlackTreeNode<T> parent;
public RedBlackTreeNode(T data) {
this.data = data;
leftChild = null;
rightChild = null;
parent = null;
color = null;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public color getColor() {
return color;
}
public void setColor(color color) {
this.color = color;
}
public RedBlackTreeNode<T> getLeftChild() {
return leftChild;
}
public void setLeftChild(RedBlackTreeNode<T> leftChild) {
this.leftChild = leftChild;
}
public RedBlackTreeNode<T> getRightChild() {
return rightChild;
}
public void setRightChild(RedBlackTreeNode<T> rightChild) {
this.rightChild = rightChild;
}
public RedBlackTreeNode<T> getParent() {
return parent;
}
public void setParent(RedBlackTreeNode<T> parent) {
this.parent = parent;
}
}
红黑树类:
import redBlackTree.RedBlackTreeNode.color;
public class RedBlackTree<T extends Comparable<T>> {
private RedBlackTreeNode<T> sentinel
;
private RedBlackTreeNode<T> root;
public RedBlackTree() {
sentinel = new RedBlackTreeNode<>(null);
sentinel.setColor(color.BLACK);
root = null;
}
public void redBlackInsert(RedBlackTreeNode<T> z) {
RedBlackTreeNode<T> y, x;
int temp;
y = sentinel;
x = this.root;
//Getting NullPointerException in the below while loop condition
while ((x.getData()) != null) {
y = x;
temp = z.getData().compareTo(x.getData());
if (temp < 0) {
x = x.getLeftChild();
} else {
x = x.getRightChild();
System.out.println("Right child of X: " + x);
System.out.println("Sentinel: " + x);
}
}
z.setParent(y);
if (y.getData() != null) {
temp = z.getData().compareTo(y.getData());
if (temp < 0) {
y.setLeftChild(z);
} else {
y.setRightChild(z);
}
} else {
root = z;
}
z.setLeftChild(sentinel);
z.setRightChild(sentinel);
z.setColor(color.RED);
redBlackInsertFix(z);
System.out.println("First node inserted");
}
private void redBlackInsertFix(RedBlackTreeNode<T> z) {
while (z.getParent().getColor() == color.RED) {
if (z.getParent() == z.getParent().getParent().getLeftChild()) {
RedBlackTreeNode<T> y;
y = z.getParent().getParent().getRightChild();
if (y.getColor() == color.RED) {
z.getParent().setColor(color.BLACK);
y.setColor(color.BLACK);
z.getParent().getParent().setColor(color.RED);
z = z.getParent().getParent();
} else if (z == z.getParent().getRightChild()) {
z = z.getParent();
leftRotate(z);
}
z.getParent().setColor(color.BLACK);
z.getParent().getParent().setColor(color.RED);
rightRotate(z.getParent().getParent());
} else {
RedBlackTreeNode<T> y;
y = z.getParent().getParent().getLeftChild();
if (y.getColor() == color.RED) {
z.getParent().setColor(color.BLACK);
y.setColor(color.BLACK);
z.getParent().getParent().setColor(color.RED);
z = z.getParent().getParent();
} else if (z == z.getParent().getLeftChild()) {
z = z.getParent();
rightRotate(z);
}
z.getParent().setColor(color.BLACK);
z.getParent().getParent().setColor(color.RED);
leftRotate(z.getParent().getParent());
}
}
root.setColor(color.BLACK);
}
private void rightRotate(RedBlackTreeNode<T> y) {
RedBlackTreeNode<T> x;
x = y.getLeftChild();
y.setLeftChild(x.getRightChild());
if (x.getRightChild() != sentinel) {
x.getRightChild().setParent(y);
}
x.setParent(y.getParent());
if (y.getParent() == sentinel) {
root = x;
} else if (y == y.getParent().getLeftChild()) {
y.getParent().setLeftChild(x);
} else {
y.getParent().setRightChild(x);
}
x.setRightChild(y);
y.setParent(x);
}
private void leftRotate(RedBlackTreeNode<T> x) {
RedBlackTreeNode<T> y;
y = x.getRightChild();
x.setRightChild(y.getLeftChild());
if (y.getLeftChild() != sentinel) {
y.getLeftChild().setParent(x);
}
y.setParent(x.getParent());
if (x.getParent() == sentinel) {
root = y;
} else if (x == x.getParent().getLeftChild()) {
x.getParent().setLeftChild(y);
} else {
x.getParent().setRightChild(y);
}
y.setLeftChild(x);
x.setParent(y);
}
public void inOrderTraversal(RedBlackTreeNode<T> x) {
if (x.getData() != sentinel.getData()) {
inOrderTraversal(x.getLeftChild());
System.out.println(x.getData());
inOrderTraversal(x.getRightChild());
}
}
public RedBlackTreeNode<T> getRoot() {
return root;
}
}
这是具有 main 方法的类:
public class RedBlackTreeDriver {
public static void main(String[] args) {
RedBlackTreeNode<Integer> one = new RedBlackTreeNode<>(50);
RedBlackTreeNode<Integer> two = new RedBlackTreeNode<>(55);
RedBlackTreeNode<Integer> three = new RedBlackTreeNode<>(48);
RedBlackTree<Integer> rbt = new RedBlackTree<>();
//System.out.println(rbt.getRoot());
//NullPointerException
rbt.redBlackInsert(one);
System.out.println("ROOT: "+ rbt.getRoot());
rbt.redBlackInsert(two);
rbt.redBlackInsert(three);
System.out.println(rbt.getRoot());
rbt.inOrderTraversal(rbt.getRoot());
}
}
在插入每个具有值的节点后,我正在尝试添加一个哨兵节点(将数据属性设置为“null”)。所以,在添加第一个节点之后,我应该能够沿着树(寻找哨兵)并将新节点添加到哨兵的父节点。
我在 Red Black Tree 类中遇到空指针异常。 到目前为止,我已经尝试了我所知道的几乎所有东西。 有人可以指导我吗?
【问题讨论】:
标签: java algorithm data-structures red-black-tree clrs