老哥版紅黑樹
阿新 • • 發佈:2018-04-08
紅黑樹public class RBTree
{
Node root;
{
Node root;
public 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(); }
}
老哥版紅黑樹