Red Black Tree (Java)

From LiteratePrograms

Jump to: navigation, search
Other implementations: Java | Python

Implementation

package org.presci.tree.rb;
public class Entry<K extends Comparable<? super K>> {
	private K data;
	private Entry<K> parent;
	private Entry<K> left;
	private Entry<K> right;
	private boolean red = true;
	public Entry(K data) {
		this.data = data;
	}
	public Entry(K data, Entry<K> parent) {
		this.data = data;
		this.parent = parent;
	}
	public Entry(K data, Entry<K> parent, boolean red) {
		this.data = data;
		this.parent = parent;
		this.red = red;
	}
	public K getData() {
		return data;
	}
	public void setData(K data) {
		this.data = data;
	}
	public Entry<K> getParent() {
		return parent;
	}
	public void setParent(Entry<K> parent) {
		this.parent = parent;
	}
	public Entry<K> getLeft() {
		return left;
	}
	public void setLeft(Entry<K> left) {
		this.left = left;
	}
	public Entry<K> getRight() {
		return right;
	}
	public void setRight(Entry<K> right) {
		this.right = right;
	}
	public boolean isRed() {
		return red;
	}
	public void setRed(boolean red) {
		this.red = red;
	}
	public Entry<K> getUncle() {
		if (this.parent != null && this.parent.parent != null) {
			if (this.parent.parent.left != this.parent) {
				return this.parent.parent.left;
			} else {
				return this.parent.parent.right;
			}
		}
		return null;
	}
	public Entry<K> getGrandParent() {
		if (this.parent != null && this.parent.parent != null) {
			return this.parent.parent;
		}
		return null;
	}
	@Override
	public String toString() {
		return data + " -> " + strLeft() + " " + (red ? "RED" : "BLACK")  + " {"
				+ (parent != null ? parent.toString() : "root") + "}";
	}
	private String strLeft(){
		Boolean bool = isLeft();
		if ( bool != null){
			if (bool){
				return "[L]";
			}else {
				return "[R]";
			}
		}
		return "";
	}
	public Boolean isLeft() {
		if ( this.parent != null){
			if ( this.parent.left == this){
				return true;
			}
			return false;
		}
		return null;
	}
}



Implementation

package org.presci.tree.rb;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
public class RBTree<L extends Comparable<? super L>> {
	private Entry<L> data;
	public void add(L arg0) {
		if (data == null) {
			data = new Entry<L>(arg0, null, false);
			return;
		}
		_add(arg0);
	}
	private void _add(L arg0) {
		if (data.getData() == arg0) {
			System.out.println("Duplicate Value : " + data);
			return;
		}
		Entry<L> p = data;
		Entry<L> dt = new Entry<L>(arg0);
		while ( true){
			int n = arg0.compareTo(p.getData());
			if ( n < 0){
				if ( p.getLeft() != null){
					p = p.getLeft();
				}else {
					p.setLeft(dt);
					dt.setParent(p);
					break;
				}
			}else {
				if (p.getRight() != null) {
					p = p.getRight();
				} else {
					p.setRight(dt);
					dt.setParent(p);
					break;
				}
			}
		}
		rebalance( dt);
	}
	private void rebalance(Entry<L> dt) {
		// Cond. 1
		if (dt.getParent() == null) {
			dt.setRed(false);
			return;
		}
		// Cond. 2
		if (!dt.getParent().isRed()) {
			return;
		}
		// Cond. 3
		if (dt.getUncle() != null && dt.getUncle().isRed()) {
			dt.getUncle().setRed(false);
			dt.getParent().setRed(false);
			if (dt.getGrandParent() != null) {
				dt.getGrandParent().setRed(true);
				this.rebalance(dt.getGrandParent());
				return;
			}
		}
		this.pivot_rebalance(dt);
	}
	private void pivot_rebalance(Entry<L> dt) {
		/* Check if the parent is right or left */
		if (dt.getParent().equals(dt.getGrandParent().getLeft())) {
			// the parent is left parent
			/*
			 * True - dt is the left child, left straight line pivot around the
			 * parent
			 */
			boolean b = dt.equals(dt.getParent().getLeft());
			if (b){
				pivotright(dt.getParent(), b);
			}else {
				pivotright ( dt, b);
			}
			/*
			 * False dt is the right child pivot around the dt rearrange and
			 * pivot
			 */
		} else {
			// the parent is right parent
			/*
			 * True dt is the right child of right parent. Straight line pivot
			 * around the parent
			 */
			boolean b = dt.equals(dt.getParent().getRight());
			if (b){
				pivotleft(dt.getParent(), b);
			}else {
				pivotleft(dt, b);
			}
			/*
			 * False dt is the left child pivot around the dt rearrange and
			 * pivot
			 */
		}
	}
	@SuppressWarnings(value = { "unused" })
	private void pivotright(Entry<L> arg0, final boolean arg1) {
		// true means parent
		Entry<L> y = arg0; // node
		Entry<L> b = arg1? null:y.getLeft(); // left
		Entry<L> c = y.getRight();// right
		Entry<L> x = arg1?y.getLeft():y.getParent();
		Entry<L> z = arg1? y.getParent(): y.getGrandParent();
		Entry<L> gg = arg1? y.getGrandParent(): y.getGrandParent().getParent();
		Boolean isroot = z.isLeft();
		if (!arg1) {
			x.setRight(b);
			if (b != null)
				b.setParent(x);
			z.setLeft(y);
			y.setParent(z);
			y.setLeft(x);
			x.setParent(y);
		}
		z.setLeft(c);
		if (c != null)
			c.setParent(z);
		y.setRight(z);
		z.setParent(y);
		if (isroot == null) {
			y.setParent(null);
			this.data = y;
		} else if (isroot) {
			gg.setLeft(y);
			y.setParent(gg);
		} else {
			gg.setRight(y);
			y.setParent(gg);
		}
		z.setRed(true);
		x.setRed(true);
		y.setRed(false);
		if ( gg != null)
		rebalance(gg);
	}
	@SuppressWarnings(value = { "unused" })
	private void pivotleft(Entry<L> arg0, final boolean arg1) {
		// true means parent
		Entry<L> y = arg0; // node
		Entry<L> b = y.getLeft(); // left
		Entry<L> c = arg1? null:y.getRight();
		Entry<L> z = arg1?y.getRight():y.getParent();
		Entry<L> x = arg1?y.getParent():y.getGrandParent();
		Entry<L> gg = arg1?y.getGrandParent():y.getGrandParent().getParent();
		Boolean isroot = x.isLeft();
		if (!arg1) {
			z.setLeft(c);
			if (c != null)
				c.setParent(z);
			x.setRight(y);
			y.setRight(z);
			z.setParent(y);
			y.setParent(x);
		}
		x.setRight(b);
		if (b != null)
			b.setParent(x);
		y.setLeft(x);
		x.setParent(y);
		if (isroot == null) {
			y.setParent(null);
			this.data = y;
		} else if (isroot) {
			gg.setLeft(y);
			y.setParent(gg);
		} else {
			gg.setRight(y);
			y.setParent(gg);
		}
		x.setRed(true);
		if ( z != null) z.setRed(true);
		y.setRed(false);
		if (gg != null)
			rebalance(gg);
	}
	public void printInorder() {
		_printInorder(data);
	}
	private void _printInorder(Entry<L> data2) {
		if (data2.getLeft() != null) {
			_printInorder(data2.getLeft());
		}
		System.out.println(data2);
		if (data2.getRight() != null) {
			_printInorder(data2.getRight());
		}
	}
	public List<L> getList(){
		Stack<Entry<L>> nodes = new Stack<Entry<L>>();
		List<L> list = new LinkedList<L>();
		Entry<L> node = data;
		while ( !nodes.isEmpty() || null != node){
			if ( null != node){
				// nodes.push(node);
				nodes.push(node);
				node= node.getLeft();
			}else {
				node = nodes.pop();
				// System.out.println(node.getData());
				list.add( node.getData());
				node = node.getRight();
			}
		}
		return list;
	}
	public boolean exist(L arg0){
		return _exist(data, new Entry<L>(arg0));
	}
	private boolean _exist(Entry<L> arg0, Entry<L> arg1){
		if ( arg0 == null){
			return false;
		}
		int n = arg1.getData().compareTo(arg0.getData());
		if (n ==0){
			return true;
		}
		if ( n <0){
			return _exist( arg0.getLeft(), arg1);
		}else if ( n > 0){
			return _exist( arg0.getRight(), arg1);
		}
		return false;
	}
}

Deletion BST deletion can be applied to the implementation to delete any node.

Download code
Views