From 384f588c2d832ce9f58ed6be2b5183cdca09bb96 Mon Sep 17 00:00:00 2001 From: Jack <34185019+jack870131@users.noreply.github.com> Date: Tue, 24 Apr 2018 18:46:14 +0800 Subject: [PATCH] Add files via upload The algorithm of red black tree implemented by Java --- Data Structures/Trees/RedBlackBST.java | 330 +++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 Data Structures/Trees/RedBlackBST.java diff --git a/Data Structures/Trees/RedBlackBST.java b/Data Structures/Trees/RedBlackBST.java new file mode 100644 index 00000000..08a8fb07 --- /dev/null +++ b/Data Structures/Trees/RedBlackBST.java @@ -0,0 +1,330 @@ +/** + * + * @author jack870131 + */ +public class RedBlackBST { + + private final int R = 0; + private final int B = 1; + + private class Node { + + int key = -1, color = B; + Node left = nil, right = nil, p = nil; + + Node(int key) { + this.key = key; + } + } + + private final Node nil = new Node(-1); + private Node root = nil; + + public void printTree(Node node) { + if (node == nil) { + return; + } + printTree(node.left); + System.out.print(((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + printTree(node.right); + } + + public void printTreepre(Node node) { + if (node == nil) { + return; + } + System.out.print(((node.color == R) ? " R " : " B ") + "Key: " + node.key + " Parent: " + node.p.key + "\n"); + printTree(node.left); + printTree(node.right); + } + + private Node findNode(Node findNode, Node node) { + if (root == nil) { + return null; + } + if (findNode.key < node.key) { + if (node.left != nil) { + return findNode(findNode, node.left); + } + } else if (findNode.key > node.key) { + if (node.right != nil) { + return findNode(findNode, node.right); + } + } else if (findNode.key == node.key) { + return node; + } + return null; + } + + private void insert(Node node) { + Node temp = root; + if (root == nil) { + root = node; + node.color = B; + node.p = nil; + } else { + node.color = R; + while (true) { + if (node.key < temp.key) { + if (temp.left == nil) { + temp.left = node; + node.p = temp; + break; + } else { + temp = temp.left; + } + } else if (node.key >= temp.key) { + if (temp.right == nil) { + temp.right = node; + node.p = temp; + break; + } else { + temp = temp.right; + } + } + } + fixTree(node); + } + } + + private void fixTree(Node node) { + while (node.p.color == R) { + Node y = nil; + if (node.p == node.p.p.left) { + y = node.p.p.right; + + if (y != nil && y.color == R) { + node.p.color = B; + y.color = B; + node.p.p.color = R; + node = node.p.p; + continue; + } + if (node == node.p.right) { + node = node.p; + rotateLeft(node); + } + node.p.color = B; + node.p.p.color = R; + rotateRight(node.p.p); + } else { + y = node.p.p.left; + if (y != nil && y.color == R) { + node.p.color = B; + y.color = B; + node.p.p.color = R; + node = node.p.p; + continue; + } + if (node == node.p.left) { + node = node.p; + rotateRight(node); + } + node.p.color = B; + node.p.p.color = R; + rotateLeft(node.p.p); + } + } + root.color = B; + } + + void rotateLeft(Node node) { + if (node.p != nil) { + if (node == node.p.left) { + node.p.left = node.right; + } else { + node.p.right = node.right; + } + node.right.p = node.p; + node.p = node.right; + if (node.right.left != nil) { + node.right.left.p = node; + } + node.right = node.right.left; + node.p.left = node; + } else { + Node right = root.right; + root.right = right.left; + right.left.p = root; + root.p = right; + right.left = root; + right.p = nil; + root = right; + } + } + + void rotateRight(Node node) { + if (node.p != nil) { + if (node == node.p.left) { + node.p.left = node.left; + } else { + node.p.right = node.left; + } + + node.left.p = node.p; + node.p = node.left; + if (node.left.right != nil) { + node.left.right.p = node; + } + node.left = node.left.right; + node.p.right = node; + } else { + Node left = root.left; + root.left = root.left.right; + left.right.p = root; + root.p = left; + left.right = root; + left.p = nil; + root = left; + } + } + + void transplant(Node target, Node with) { + if (target.p == nil) { + root = with; + } else if (target == target.p.left) { + target.p.left = with; + } else + target.p.right = with; + with.p = target.p; + } + + Node treeMinimum(Node subTreeRoot) { + while (subTreeRoot.left != nil) { + subTreeRoot = subTreeRoot.left; + } + return subTreeRoot; + } + + boolean delete(Node z) { + if ((z = findNode(z, root)) == null) + return false; + Node x; + Node y = z; + int yorigcolor = y.color; + + if (z.left == nil) { + x = z.right; + transplant(z, z.right); + } else if (z.right == nil) { + x = z.left; + transplant(z, z.left); + } else { + y = treeMinimum(z.right); + yorigcolor = y.color; + x = y.right; + if (y.p == z) + x.p = y; + else { + transplant(y, y.right); + y.right = z.right; + y.right.p = y; + } + transplant(z, y); + y.left = z.left; + y.left.p = y; + y.color = z.color; + } + if (yorigcolor == B) + deleteFixup(x); + return true; + } + + void deleteFixup(Node x) { + while (x != root && x.color == B) { + if (x == x.p.left) { + Node w = x.p.right; + if (w.color == R) { + w.color = B; + x.p.color = R; + rotateLeft(x.p); + w = x.p.right; + } + if (w.left.color == B && w.right.color == B) { + w.color = R; + x = x.p; + continue; + } else if (w.right.color == B) { + w.left.color = B; + w.color = R; + rotateRight(w); + w = x.p.right; + } + if (w.right.color == R) { + w.color = x.p.color; + x.p.color = B; + w.right.color = B; + rotateLeft(x.p); + x = root; + } + } else { + Node w = x.p.left; + if (w.color == R) { + w.color = B; + x.p.color = R; + rotateRight(x.p); + w = x.p.left; + } + if (w.right.color == B && w.left.color == B) { + w.color = R; + x = x.p; + continue; + } else if (w.left.color == B) { + w.right.color = B; + w.color = R; + rotateLeft(w); + w = x.p.left; + } + if (w.left.color == R) { + w.color = x.p.color; + x.p.color = B; + w.left.color = B; + rotateRight(x.p); + x = root; + } + } + } + x.color = B; + } + + public void insertDemo() { + Scanner scan = new Scanner(System.in); + while (true) { + System.out.println("Add items"); + + int item; + Node node; + + item = scan.nextInt(); + while (item != -999) { + node = new Node(item); + insert(node); + item = scan.nextInt(); + } + printTree(root); + System.out.println("Pre order"); + printTreepre(root); + break; + } + } + + public void deleteDemo() { + Scanner scan = new Scanner(System.in); + System.out.println("Delete items"); + int item; + Node node; + item = scan.nextInt(); + node = new Node(item); + System.out.print("Deleting item " + item); + if (delete(node)) { + System.out.print(": deleted!"); + } else { + System.out.print(": does not exist!"); + } + + System.out.println(); + printTree(root); + System.out.println("Pre order"); + printTreepre(root); + } +} \ No newline at end of file