标签:红黑树
public class RBTreepublic RBTree()
{
root = null;
}
public void add(int value)
{
Node parent;
Node thisNode = new Node(value);
if (root != null) {
parent = locateParentForAdd(value);
if (parent == null) {
return;
} else {
if (value > parent.value) {
parent.rightChild = thisNode;
} else if (value < parent.value) {
parent.leftChild = thisNode;
}
thisNode.parent = parent;
}
} else {
root = thisNode;
}
rbfy(thisNode);
}
public Node locateParentForAdd(int value)
{
Node current = root;
while (true) {
if (value > current.value) {
if (current.rightChild == null) {
return current;
} else {
current = current.rightChild;
}
} else if (value < current.value) {
if (current.leftChild == null) {
return current;
} else {
current = current.leftChild;
}
} else {
return null;
}
}
}
public Node searchNode(int value)
{
Node current = root;
if (root == null) {
return null;
}
while (true) {
if (value > current.value) {
if (current.rightChild == null) {
return null;
} else {
current = current.rightChild;
}
} else if (value < current.value) {
if (current.leftChild == null) {
return null;
} else {
current = current.leftChild;
}
} else {
return current;
}
}
}
public void remove(int value)
{
Node nodeToBeRemoved = locateNodeToBeRemoved(value);
if (nodeToBeRemoved == null) {
return;
} else {
if (nodeToBeRemoved.isRed()) {
nodeToBeRemoved.delete();
} else {
removeBlackLeafNode(nodeToBeRemoved, true);
}
}
}
public void removeBlackLeafNode(Node current, boolean really)
{
if (current.isRoot()) {
if (really) {
root = null;
}
return;
}
if (current.parent.isRed()) {
current.parent.setBlack();
current.getBrother().setRed();
if (really) {
current.delete();
}
} else if (current.getBrother().isRed()) {
if (current.isLeftChild()) {
leftRotate(current.parent);
} else {
rightRotate(current.parent);
}
current.parent.setRed();
current.getBrother().setBlack();
removeBlackLeafNode(current, true);
} else if (current.getBrother().hasChild()) {
if (current.isLeftChild() && current.getBrother().hasRightChild()) {
leftRotate(current.parent);
current.parent.getBrother().setBlack();
if (really) {
current.delete();
}
} else if (current.isRightChild() && current.getBrother().hasLeftChild()) {
rightRotate(current.parent);
current.parent.getBrother().setBlack();
if (really) {
current.delete();
}
} else if (current.isLeftChild() && current.getBrother().hasLeftChild()) {
rightRotate(current.getBrother());
current.getBrother().setBlack();
current.getBrother().rightChild.setRed();
removeBlackLeafNode(current, true);
} else if (current.isRightChild() && current.getBrother().hasRightChild()) {
leftRotate(current.getBrother());
current.getBrother().setBlack();
current.getBrother().leftChild.setRed();
removeBlackLeafNode(current, true);
}
} else {
if (really) {
current.delete();
}
current.getBrother().setRed();
removeBlackLeafNode(current.parent, false);
}
}
public Node locateNodeToBeRemoved(int value)
{
Node originalNode = searchNode(value);
if (originalNode == null) {
return null;
}
if (originalNode.isLeaf()) {
return originalNode;
} else {
return replaceAndGetEmptyNode(originalNode);
}
}
public Node replaceAndGetEmptyNode(Node current)
{
Node nodeToBeEmpty;
if (current.hasLeftChild()) {
nodeToBeEmpty = getRightMostNodeOfLeftTree(current);
} else {
nodeToBeEmpty = getLeftMostNodeOfRightTree(current);
}
current.value = nodeToBeEmpty.value;
if (nodeToBeEmpty.isLeaf()) {
return nodeToBeEmpty;
} else {
return replaceAndGetEmptyNode(nodeToBeEmpty);
}
}
public Node getRightMostNodeOfLeftTree(Node current)
{
current = current.leftChild;
while (true) {
if (current.hasRightChild()) {
current = current.rightChild;
} else {
return current;
}
}
}
public Node getLeftMostNodeOfRightTree(Node current)
{
current = current.rightChild;
while (true) {
if (current.hasLeftChild()) {
current = current.leftChild;
} else {
return current;
}
}
}
public void rbfy(Node current)
{
if (current.isRoot()) {
current.setBlack();
return;
}
Node parent = current.parent;
if (parent.isBlack()) {
return;
}
Node uncle = current.getUncle();
Node grandParent = current.getGrandParent();
if (uncle != null && uncle.isRed()) {
grandParent.setRed();
current.parent.setBlack();
current.getUncle().setBlack();
rbfy(grandParent);
} else {
boolean isLeftChild = current.isLeftChild();
boolean isParentLeftChild = current.parent.isLeftChild();
if (isLeftChild && isParentLeftChild) {
rightRotate(grandParent);
parent.setBlack();
grandParent.setRed();
} else if (!isLeftChild && !isParentLeftChild) {
leftRotate(grandParent);
parent.setBlack();
grandParent.setRed();
} else {
if (isLeftChild) {
rightRotate(parent);
} else {
leftRotate(parent);
}
rbfy(current);
}
}
}
public void rightRotate(Node current)
{
Node parent = current.parent;
boolean isLeftChild = false;
if (parent != null) {
isLeftChild = current.isLeftChild();
}
Node leftNode = current.leftChild;
Node temp = leftNode.rightChild;
leftNode.rightChild = current;
current.parent = leftNode;
current.leftChild = temp;
if (temp != null) {
temp.parent = current;
}
if (parent != null) {
if (isLeftChild) {
parent.leftChild = leftNode;
} else {
parent.rightChild = leftNode;
}
} else {
root = leftNode;
}
leftNode.parent = parent;
}
public void leftRotate(Node current)
{
Node parent = current.parent;
boolean isLeftChild = false;
if (parent != null) {
isLeftChild = current.isLeftChild();
}
Node rightNode = current.rightChild;
Node temp = rightNode.leftChild;
rightNode.leftChild = current;
current.parent = rightNode;
current.rightChild = temp;
if (temp != null) {
temp.parent = current;
}
if (parent != null) {
if (isLeftChild) {
parent.leftChild = rightNode;
} else {
parent.rightChild = rightNode;
}
} else {
root = rightNode;
}
rightNode.parent = parent;
}
public void print()
{
if (root != null) {
_print(root);
}
}
public void _print(Node current)
{
if (current == null) {
return;
}
Node leftChild = current.leftChild;
Node rightChild = current.rightChild;
_print(leftChild);
System.out.println(current);
_print(rightChild);
}
public static class Node
{
public static final boolean RED = true;
public static final boolean BLACK = false;
public boolean color;
public int value;
public Node parent;
public Node leftChild;
public Node rightChild;
public Node(int value)
{
this.value = value;
this.color = RED;
this.parent = null;
this.leftChild = null;
this.rightChild = null;
}
public boolean isLeftChild()
{
Node parent = this.parent;
if (parent.leftChild == this) {
return true;
} else {
return false;
}
}
public boolean isRightChild()
{
Node parent = this.parent;
if (parent.rightChild == this) {
return true;
} else {
return false;
}
}
public void delete()
{
if (isRoot()) {
return;
}
Node parent = this.parent;
if (isLeftChild()) {
parent.leftChild = null;
} else {
parent.rightChild = null;
}
}
public void setRed()
{
color = RED;
}
public void setBlack()
{
color = BLACK;
}
public boolean isRed()
{
if (color == RED) {
return true;
} else {
return false;
}
}
public boolean isBlack()
{
if (color == BLACK) {
return true;
} else {
return false;
}
}
public Node getGrandParent()
{
return this.parent.parent;
}
public Node getUncle()
{
Node parent = this.parent;
Node grandParent = getGrandParent();
if (parent.isLeftChild()) {
return grandParent.rightChild;
} else {
return grandParent.leftChild;
}
}
public boolean isLeaf()
{
if (leftChild == null && rightChild == null) {
return true;
} else {
return false;
}
}
public boolean hasLeftChild()
{
if (leftChild != null) {
return true;
} else {
return false;
}
}
public boolean hasRightChild()
{
if (rightChild != null) {
return true;
} else {
return false;
}
}
public Node getBrother()
{
Node parent = this.parent;
if (isLeftChild()) {
return parent.rightChild;
} else {
return parent.leftChild;
}
}
public boolean hasChild()
{
if (leftChild != null || rightChild != null) {
return true;
} else {
return false;
}
}
public boolean isRoot()
{
if (parent == null) {
return true;
} else {
return false;
}
}
@Override
public String toString()
{
String colorStr;
if (isRed()) {
colorStr = "red";
} else {
colorStr = "black";
}
StringBuilder builder = new StringBuilder(100);
builder.append(colorStr);
builder.append(value);
builder.append(" - ");
builder.append(parent);
return builder.toString();
}
}
public static void main(String[] agrs) throws Exception
{
RBTree tree = new RBTree();
tree.add(11);
tree.add(2);
tree.add(1);
tree.add(7);
tree.add(5);
tree.add(8);
tree.add(14);
tree.add(15);
tree.add(4);
/*
tree.remove(4);
tree.remove(2);
tree.remove(1);
tree.remove(7);
tree.remove(5);
tree.remove(8);
tree.remove(11);
tree.remove(14);
tree.remove(15);
*/
tree.print();
}
}
标签:红黑树
原文地址:http://blog.51cto.com/13692362/2095462