diff --git a/Data Structures/Trees/RedBlackBST.java b/Data Structures/Trees/RedBlackBST.java
new file mode 100644
index 000000000000..08a8fb072e2d
--- /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