In my siftDown method for my heap, I'm getting an infinite loop I believe that is being caused by my if(current.isLeaf()) line. Can anyone help me so that I can get Node n down to where it becomes a leaf or when it stops being smaller than its children?
public void siftDown(Node<V> n) {
Node<V> current = n;
boolean notDone = true;
while (notDone) {
if (!current.isLeaf()) {
current = n;
if ((current.data.compareTo(current.left.data) < 0)
&& (current.left.data.compareTo(current.right.data) >= 0)) {
swapValues(current, current.left);
current = current.left;
} else if ((current.data.compareTo(current.right.data) < 0)
&& (current.right.data.compareTo(current.left.data) > 0)) {
swapValues(current, current.right);
current = current.right;
if (current.isLeaf()) {
notDone = false;
}
}
} else {
notDone = false;
}
}
}
public void swapValues(Node<V> x, Node<V> y) {
V temp = x.data;
x.data = y.data;
y.data = temp;
}
public boolean isLeaf() { //inside my node class
if (left == null && right == null)
return true;
else
return false;
}
Related
I am trying to implement a getHeight method that has a o(1) time complexity. To do this I am aiming to assign every node their own height and to return the height of the root with the getHeight method. To do this I need to update the height of the nodes everytime I add or remove.
Thus, I chose to do this:
private void updateHeight(Node node)
{
if (node == null)
{
return;
}
updateHeight(node.left);
updateHeight(node.right);
this.helpHeight(node);
}
private void helpHeight(Node node)
{
if (this.isLeaf(node))
{
node.height = 0;
}
else if (node.left == null)
{
node.height = node.right.height + 1;
}
else if (node.right == null)
{
node.height = node.left.height + 1;
}
else
{
node.height = 1 + max(node.left.height, node.right.height);
}
}
private int max(int height, int height2) {
if (height > height2)
{
return height;
}
else
{
return height2;
}
}
public int height()
{
return root.height + 1;
}
Then I will call the updateHeight(Node node) method with the root as the parameter. However, it's not working when I test it this way:
public static void main(String[] arg)
{
BST bst = new BST();
bst.add("a");
bst.add("b");
bst.add("c");
System.out.println(bst.height());
bst.remove("c");
System.out.println(bst.height());
}
It's returning 2, then 2.
Just in case, here is my add method:
public boolean add(E e) throws NullPointerException
{
if (e == null)
{
throw new NullPointerException("Error: Cannot add a null object to the tree.");
}
if (root == null)
{
root = new Node(e);
return true;
}
Node current = root;
while (current != null ) {
if (current.data.compareTo(e) > 0) {
//add in the left subtree
if (current.left == null ) {
current.left = new Node (e);
size++;
this.updateHeight(root);
return true;
}
else {
current = current.left;
}
}
else if (current.data.compareTo(e) < 0) {
//add in the right subtree
if (current.right == null ) {
size++;
this.updateHeight(root);
current.right = new Node(e);
return true;
}
else {
current = current.right;
}
}
else { //duplicate
return false;
}
}
//should never get to this line
return false;
}
The error I believe starts on line 102: int treeDepth(Node Node) because when I run the code with a regular while loop with a count, it runs and displays a tree. But as soon as I change the while condition to while (treeDepth(this.root) <= 5) it runs but displays nothing, and I get no errors. Trying to make it so the tree that is created doesn't have a depth larger than 5.
import java.io.*;
import java.util.*;
class Node {
int value;
Node left;
Node right;
Node(int value) {
this.value = value;
right = null;
left = null;
}
}
public class treeStructureBinary{
Node root;
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
void appMain(String[] args) {
createBinaryTree();
}
private Node addRecursive(Node current, int value) {
if (current == null) {
return new Node(value);
}
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
return current;
}
return current;
}
public void add(int value) {
this.root = addRecursive(this.root, value);
}
public treeStructureBinary createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
int [] array = new int[89];
int counter = 0;
boolean check = true;
while (treeDepth(this.root) <= 5)
{
Random rand = new Random();
int n = rand.nextInt(89) + 10;
for(int z = 0; z <= counter; z++)
{
if ( n == array[z])
{
check = false;
break;
}
}
if (check == true)
{
bt.add(n);
array[counter] = n;
counter++;
}
check = true;
}
bt.traverseLevelOrder();
return bt;
}
public void traverseLevelOrder() {
if (this.root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(this.root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
System.out.print(" " + node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
nodes.add(node.right);
}
}
}
int treeDepth(Node Node){
if (Node == null) {
return 0;
}else {
int lDepth = treeDepth(Node.left);
int rDepth = treeDepth(Node.right);
if (lDepth > rDepth) {
System.out.println("lDepth" + "\n");
return (lDepth + 1);
}else {
System.out.println("rDepth" + "\n");
return (rDepth + 1);
}
}
}
}
I think your addRecursive never actually adds the node to the tree--or always adds it? Anyway it looks funky. I'd focus on that for a bit.
This code in particular:
if (value < current.value) {
current.left = addRecursive(current.left, value);
} else if (value > current.value) {
current.right = addRecursive(current.right, value);
} else {
return current;
}
always forces an assign (even if it's not a leaf) and the final else will only execute when value == current.value which is probably not what you want.
I don't really want to go much further because it looks homeworky and you'll gain more figuring it out yourself.
It might work anyway (You just may be re-assigning every node at every level) but I'm not sure without running it.
Anyway, if this is a homework assignment I'd really like to commend you on your style, it's one of the best I've seen posted here for a homework-like question.
Main problem here is that you are working on two different trees.
First you create one tree in main function:
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
Then you create another one in createBinaryTree method:
public SthApplication createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
See, you used new keyword twice, so there will be two objects.
Later in your app you refer to this.root (which is the one from main), but some methods use local variable bt.
In example, treeDepth(this.root) operates on different tree then the bt.add(n), so it goes into infinite loop.
If you solve that problem, you will know how to finish the rest.
Thanks guys I figured it out!
import java.io.*;
import java.util.*;
class Node {
int value;
int balancefactor;
int nodex;
Node left;
Node right;
Node(int value, int balancefactor, int nodex) {
this.value = value;
this.balancefactor = balancefactor;
this.nodex = nodex;
this.right = null;
this.left = null;
}
}
public class treeStructureBinary{
Node root;
public static void main(String[] args) {
treeStructureBinary bn =new treeStructureBinary();
bn.appMain(args);
}
void appMain(String[] args) {
int count = args.length;
if (count >1) {
count = 1;
}
String [] cmdln = {""};
for (int i=0;i<count;i++) {
cmdln[i]=args[i];
}
if (cmdln[0].equals("BT")){
createBinaryTree();
} else if (cmdln[0].equals("AVL")) {
} else {
System.out.println("Please enter BT or AVL to choose the type of
tree.");
}
}
private Node addRecursive(Node current, int value, int balancefactor, int
nodex) {
if (current == null) {
return new Node(value, balancefactor, nodex);
} if (value < current.value) {
balancefactor++;
nodex=(nodex*2);
current.left = addRecursive(current.left, value, balancefactor,
nodex);
} else if (value > current.value) {
balancefactor++;
nodex=(nodex*2)+1;
current.right = addRecursive(current.right, value, balancefactor,
nodex);
} else {
return current;
}
return current;
}
public void add(int value) {
int balancefactor=1;
int nodex=0;
this.root = addRecursive(this.root, value, balancefactor, nodex);
}
public treeStructureBinary createBinaryTree() {
treeStructureBinary bt = new treeStructureBinary();
int [] array = new int[89];
int counter = 0;
boolean check = true;
int temp = 0;
while (temp < 5) {
Random rand = new Random();
int n = rand.nextInt(89) + 10;
for(int z = 0; z <= counter; z++) {
if ( n == array[z]) {
check = false;
break;
}
}
if (check == true) {
bt.add(n);
array[counter] = n;
counter++;
}
check = true;
temp = bt.treeDepth();
}
bt.traverseLevelOrder();
Scanner reader =new Scanner(System.in);
System.out.println("\n\nEnter a number to delete or 0 to exit");
int input = reader.nextInt();
Boolean isMatch = true;
while (input!=0) {
for(int p = 0; p < counter; p++)
{
//System.out.println(array[p]);
if (input != array[p])
{
isMatch = false;
}
else
{
isMatch = true;
array[p] = 0;
break;
}
}
if (isMatch == false )
{
System.out.println("Error, number not found.");
}
bt.nodeDelete(input);
bt.traverseLevelOrder();
System.out.println("\n\nEnter a number to delete or 0 to exit");
input = reader.nextInt();
}
return bt;
}
public void traverseLevelOrder() {
int count = 0;
int outer = 31;
int inner = 30;
int lastnode= 0;
int check = 0;
if (this.root == null) {
return;
}
Queue<Node> nodes = new LinkedList<>();
nodes.add(this.root);
while (!nodes.isEmpty()) {
Node node = nodes.remove();
if (count < node.balancefactor) {
System.out.print("\n");
for (int i=0; i<outer; i++) {
System.out.print(" ");
}
inner=outer;
outer=outer/2;
count++;
lastnode=0;
check=0;
}
check=((node.nodex-lastnode));
for (int i=0; i<(inner*check*2);i++) {
System.out.print(" ");
}
if (check >1) {
for (int j=0;j<check;j++) {
System.out.print(" ");
}
}
lastnode=node.nodex;
System.out.print(node.value);
if (node.left != null) {
nodes.add(node.left);
}
if (node.right != null) {
if (node.right==null &&lastnode == 0) {
if (count==5) {
break;
}
System.out.print(" ");
}
nodes.add(node.right);
}
}
}
int treeDepth(){
int temp = treeDepthRecursive(this.root);
return temp;
}
int treeDepthRecursive(Node current) {
if (current == null) {
return 0;
} else {
int lDepth = treeDepthRecursive(current.left);
int rDepth = treeDepthRecursive(current.right);
if (lDepth > rDepth) {
return (lDepth + 1);
} else {
return (rDepth + 1);
}
}
}
public void nodeDelete(int value) {
nodeDeleteRecursive(root, value);
}
public Node nodeDeleteRecursive(Node current, int value) {
if (current == null) {
return null;
}
if (value == current.value) {
if (current.left ==null && current.right==null) {
return null;
}
if (current.right==null) {
return current.left;
}
if (current.left==null) {
return current.right;
}
int sValue = findSmall(current.right);
current.value = sValue;
current.right = nodeDeleteRecursive(current.right, sValue);
return current;
}
if (value < current.value) {
current.left = nodeDeleteRecursive(current.left, value);
return current;
}
current.right =nodeDeleteRecursive(current.right, value);
return current;
}
public int findSmall(Node root) {
return root.left == null?(root.value):(findSmall(root.left));
}
}
How do you count number of branches, in this case branches with even integers. Here's what I have so far. It seems to work for a couple of the cases.
public int evenBranches() {
return evenBranches(overallRoot);
}
private int evenBranches(IntTreeNode root) {
if (root == null) {
return 0;
}
int val = 0;
if (root.left != null) {
val += evenBranches(root.left);
} else if (root.right != null) {
val += evenBranches(root.right);
}
if (root.data % 2 == 0) {
return val + 1;
} else {
return val;
}
}
You can modify the evenBranches() method as below: I think It will cover all edge cases, If any testcase is left, let me know, I will fix it.
public int evenBranches() {
return evenBranches(overallRoot, 0);
}
private int evenBranches(IntTreeNode root, int count) {
if(root == null || (root.left == null && root.right == null)) {
return count;
}
if(root.data % 2 == 0) {
count++;
}
count += evenBranches(root.left, count);
count += evenBranches(root.right, count);
return count;
}
You may need to remove the else condition when checking the occurrences in right branch. Otherwise it will check only one side. eg:
private int evenBranches(IntTreeNode root) {
if (root == null) {
return 0;
}
int val = 0;
if (root.left != null) {
val += evenBranches(root.left);
}
if (root.right != null) {
val += evenBranches(root.right);
}
if (root.data % 2 == 0) {
return val + 1;
} else {
return val;
}
}
You can very well achieve the desired results by using a global variable, and applying BFS (breadth first search) on your tree, in this manner:
int evencount = 0; // global-var.
public int evenBranches() {
evenBranches(overallRoot);
return evencount;
}
private void evenBranches(IntTreeNode root) {
if(!root) return;
if( (root.left || root.right) && (root.data % 2 == 0)){
evencount++;
}
evenBranches(root.left);
evenBranches(root.right);
}
Here is my code:
public class RecipeBook {
private class Node {
private Recipe mData;
private Node mNext;
private Node mPrev;
public Node(Recipe data, Node next, Node prev) {
mData = data;
mNext = next;
mPrev = prev;
}
}
private Node mHead;
private Node mTail;
private int mCount;
public RecipeBook() {
}
public void add(Recipe itemToAdd) {
Node newNode = new Node(itemToAdd, null, null);
if (mHead == null)
mHead = mTail = newNode;
else {
mTail.mNext = newNode;
newNode.mPrev = mTail;
mTail = newNode;
}
mCount++;
}
public int getCount() {
return mCount;
}
public Recipe get(int index) {
Node n = mHead;
for (int i = 0; i < index; i++) {
if (n == null)
return null;
n = n.mNext;
}
return n != null ? n.mData : null;
}
public boolean remove(Recipe itemToRemove) {
Node n = mHead;
boolean check = false;
if (n == null) {
check = false;
return check;
}
while (n != null) {
if (n.mData == itemToRemove) {
if (n == mHead) {
mHead = mHead.mNext;
mHead.mPrev = null;
}
else if (n == mTail) {
mTail = mTail.mPrev;
mTail.mNext = null;
}
else {
Node prev = n.mPrev;
Node next = n.mNext;
prev.mNext = next;
next.mPrev = prev;
}
check = true;
mCount--;
return check;
}
else {
n = n.mNext;
}
}
return check;
}
public Recipe searchByName(String name) {
for (int i = 0; i < this.getCount(); i++) {
if (this.get(i).getName().equals(name))
return this.get(i);
}
return null;
}
public Recipe searchByIngredients(String target) {
for (int i = 0; i < this.getCount(); i++) {
if (this.get(i).hasIngredients(target) == true)
return this.get(i);
}
return null;
}
}
My problem is with the remove method, and I've actually checked with the debugger. The while loop works fine, and the program goes through the if statement when n.mData == itemToRemove. It removes what it's suppose to remove, no matter where the item is in the list. In addition the mCount gets smaller by one, and check becomes true, but once it gets to return it doesn't return anything. Instead it goes back to the loop, and keeps going until n is null. This would have been fine if check was remaining true, but after it goes out of the if statement without returning anything, it reverts check back to false which then makes the whole method return false. I've tried removing the return and having break which gave me the same result. I've also tried not having a return nor break while running the debugger which showed that it remained in the if statement, as if that statement was a loop.
This is a temporary solution, but try adding a break after when n.mData == itemToRemove, then return check. This should be able to give you some hints perhaps as to why your code isn't working.
public boolean remove(Recipe itemToRemove) {
Node n = mHead;
boolean check = false;
if (n == null) {
check = false;
return check;
}
while (n != null) {
if (n.mData == itemToRemove) {
if (n == mHead) {
mHead = mHead.mNext;
mHead.mPrev = null;
}
else if (n == mTail) {
mTail = mTail.mPrev;
mTail.mNext = null;
}
else {
Node prev = n.mPrev;
Node next = n.mNext;
prev.mNext = next;
next.mPrev = prev;
}
check = true;
mCount--;
break;
}
else {
n = n.mNext;
}
}
return check;
}
I am implementing a Red Black Tree with insert, search and delete functions in O (log n) time. Insert and search are working fine. However I am stuck on delete. I found this ppt slide on the internet which shows the algorithm of RBT deletion: http://www.slideshare.net/piotrszymanski/red-black-trees#btnNext on page 56 onwards. I know I am asking a bit too much but I have been stuck on this for over 2 weeks and I can't find the problem. The way I'm understanding Top-Down deletion that you have to rotate and recolor nodes accordingly until you find the predecessor of the node to be deleted. When you do find this node - which would be either a leaf or a node with one right child, replace node to be deleted data by the data of this node and delete this node like normal BST deletion, right?
This is the code I did, based on what I learnt from that slide. If anyone would be so kind to go over it, I would be more than grateful! Or at least if you think there's a better algorithm than what I'm using, please tell me!
public void delete(int element){
if (root == null){
System.out.println("Red Black Tree is Empty!");
} else {
Node X = root;
parent = null;
grandParent = null;
sibling = null;
if (isLeaf(X)){
if (X.getElement() == element){
emptyRBT();
}
} else {
if (checkIfBlack(root.getLeftChild()) && checkIfBlack(root.getRightChild())){
root.setIsBlack(false);
if (X.getElement() > element && X.getLeftChild() != null){
X = moveLeft(X);
} else if (X.getElement() < element && X.getRightChild() != null){
X = moveRight(X);
}
Step2(X, element);
} else {
Step2B(X, element);
}
}
}
root.setIsBlack(true);
}
public void Step2(Node X, int element)
{
int dir = -1;
while (!isLeaf(X)){
if (predecessor == null){ // still didn't find Node to delete
if (X.getElement() > element && X.getLeftChild() != null){
X = moveLeft(X);
dir = 0;
} else if (X.getElement() < element && X.getRightChild() != null){
X = moveRight(X);
dir = 1;
} else if (X.getElement() == element){
toDelete = X;
predecessor = inorderPredecessor(X.getRightChild());
X = moveRight(X);
}
} else { // if node to delete is already found and X is equal to right node of to delete
// move always to the left until you find predecessor
if (X != predecessor){
X = moveLeft(X);
dir = 0;
}
}
if (!isLeaf(X)){
if (!hasOneNullNode(X)){
if (checkIfBlack(X.getLeftChild()) && checkIfBlack(X.getRightChild())){
Step2A(X, element, dir);
} else {
Step2B(X, element);
}
}
}
}
removeNode(X);
if (predecessor != null){
toDelete.setElement(X.getElement());
}
}
public Node Step2A(Node X, int element, int dir) {
if (checkIfBlack(sibling.getLeftChild()) && checkIfBlack(sibling.getRightChild())) {
X = Step2A1(X);
} else if ((checkIfBlack(sibling.getLeftChild()) == false) && checkIfBlack(sibling.getRightChild())) {
X = Step2A2(X);
} else if ((checkIfBlack(sibling.getLeftChild()) && (checkIfBlack(sibling.getRightChild()) == false))) {
X = Step2A3(X);
} else if ((checkIfBlack(sibling.getLeftChild()) == false) && (checkIfBlack(sibling.getRightChild()) == false)) {
X = Step2A3(X);
}
return X;
}
public Node Step2A1(Node X) {
X.setIsBlack(!X.IsBlack());
parent.setIsBlack(!parent.IsBlack());
sibling.setIsBlack(!sibling.IsBlack());
return X;
}
public Node Step2A2(Node X) {
if (parent.getLeftChild() == sibling){
LeftRightRotation(sibling.getLeftChild(), sibling, parent);
} else RightLeftRotation(sibling.getRightChild(), sibling, parent);
X.setIsBlack(!X.IsBlack());
parent.setIsBlack(!parent.IsBlack());
return X;
}
public Node Step2A3(Node X) {
if (parent.getLeftChild() == sibling){
leftRotate(sibling);
} else if (parent.getRightChild() == sibling){
rightRotate(sibling);
}
X.setIsBlack(!X.IsBlack());
parent.setIsBlack(!parent.IsBlack());
sibling.setIsBlack(!sibling.IsBlack());
sibling.getRightChild().setIsBlack(!sibling.getRightChild().IsBlack());
return X;
}
public void Step2B(Node X, int element){
if (predecessor == null){
if (X.getElement() > element && X.getLeftChild() != null){
X = moveLeft(X);
} else if (X.getElement() < element && X.getRightChild() != null){
X = moveRight(X);
} else if (X.getElement() == element){
Step2(X, element);
}
} else {
if (X != predecessor)
X = moveLeft(X);
else Step2(X, element);
}
if (X.IsBlack()){
if (parent.getLeftChild() == sibling){
leftRotate(sibling);
} else if (parent.getRightChild() == sibling){
rightRotate(sibling);
}
parent.setIsBlack(!parent.IsBlack());
sibling.setIsBlack(!sibling.IsBlack());
Step2(X, element);
} else {
Step2B(X, element);
}
}
public void removeNode(Node X) {
if (isLeaf(X)) {
adjustParentPointer(null, X);
count--;
} else if (X.getLeftChild() != null && X.getRightChild() == null) {
adjustParentPointer(X.getLeftChild(), X);
count--;
} else if (X.getRightChild() != null && X.getLeftChild() == null) {
adjustParentPointer(X.getRightChild(), X);
count--;
}
}
public Node inorderPredecessor(Node node){
while (node.getLeftChild() != null){
node = node.getLeftChild();
}
return node;
}
public void adjustParentPointer(Node node, Node current) {
if (parent != null) {
if (parent.getElement() < current.getElement()) {
parent.setRightChild(node);
} else if (parent.getElement() > current.getElement()) {
parent.setLeftChild(node);
}
} else {
root = node;
}
}
public boolean checkIfBlack(Node n){
if (n == null || n.IsBlack() == true){
return true;
} else return false;
}
public Node leftRotate(Node n)
{
parent.setLeftChild(n.getRightChild());
n.setRightChild(parent);
Node gp = grandParent;
if (gp != null){
if (gp.getElement() > n.getElement()){
gp.setLeftChild(n);
} else if (gp.getElement() < n.getElement()){
gp.setRightChild(n);
}
} else root = n;
return n;
}
public Node rightRotate(Node n)
{
parent.setRightChild(n.getLeftChild());
n.setLeftChild(parent);
Node gp = grandParent;
if (gp != null){
if (gp.getElement() > n.getElement()){
gp.setLeftChild(n);
} else if (gp.getElement() < n.getElement()){
gp.setRightChild(n);
}
} else root = n;
return n;
}
The node is being deleted, but the tree after deletion would be black violated, which is very wrong.
The eternally confuzzled blog has top-down implementations of both insert and delete for red-black trees. It also goes through case-by-case why it works. I won't replicate it here (it's rather lengthy).
I've used that blog as a reference for implementing red-black trees in both c++ and java. As I discussed in an earlier answer, I found the implementation to be faster than std::map's bottom-up implementation of red-black trees (whatever STL came with gcc at the time).
Here's an untested, direct translation of the code to Java. I would highly suggest you test it and morph it to match your style.
private final static int LEFT = 0;
private final static int RIGHT = 1;
private static class Node {
private Node left,right;
private boolean red;
...
// any non-zero argument returns right
Node link(int direction) {
return (direction == LEFT) ? this.left : this.right;
}
// any non-zero argument sets right
Node setLink(int direction, Node n) {
if (direction == LEFT) this.left = n;
else this.right = n;
return n;
}
}
boolean remove(int data) {
if ( this.root != null ) {
final Node head = new Node(-1, null, null); /* False tree root */
Node cur, parent, grandpa; /* Helpers */
Node found = null; /* Found item */
int dir = RIGHT;
/* Set up helpers */
cur = head;
grandpa = parent = null;
cur.setLink(RIGHT, this.root);
/* Search and push a red down */
while ( cur.link(dir) != null ) {
int last = dir;
/* Update helpers */
grandpa = parent, parent = cur;
cur = cur.link(dir);
dir = cur.data < data ? RIGHT : LEFT;
/* Save found node */
if ( cur.data == data )
found = cur;
/* Push the red node down */
if ( !is_red(cur) && !is_red(cur.link(dir)) ) {
if ( is_red(cur.link(~dir)) )
parent = parent.setLink(last, singleRotate(cur, dir));
else if ( !is_red(cur.link(~dir)) ) {
Node s = parent.link(~last);
if ( s != null ) {
if (!is_red(s.link(~last)) && !is_red(s.link(last))) {
/* Color flip */
parent.red = false;
s.red = true;
cur.red = true;
}
else {
int dir2 = grandpa.link(RIGHT) == parent ? RIGHT : LEFT;
if ( is_red(s.link(last)) )
grandpa.setLink(dir2, doubleRotate(parent, last));
else if ( is_red(s.link(~last)) )
grandpa.setLink(dir2, singleRotate(parent, last));
/* Ensure correct coloring */
cur.red = grandpa.link(dir2).red = true;
grandpa.link(dir2).link(LEFT).red = false;
grandpa.link(dir2).link(RIGHT).red = false;
}
}
}
}
}
/* Replace and remove if found */
if ( found != null ) {
found.data = cur.data;
parent.setLink(
parent.link(RIGHT) == cur ? RIGHT : LEFT,
cur.link(cur.link(LEFT) == null ? RIGHT : LEFT));
}
/* Update root and make it black */
this.root = head.link(RIGHT);
if ( this.root != null )
this.root.red = false;
}
return true;
}
quick link :
http://algs4.cs.princeton.edu/33balanced/RedBlackBST.java.html
--> Caution : the code on the site is relying on two jars. In the datastructures however the dependency might be minimal. Sometimes it's enough to comment out the main method (that only serves as a test client)
If not : the jars are downloadable on the same site.
If you are looking for two weeks and studying algoritms, chances are you know about
http://algs4.cs.princeton.edu/
the website that is accompanying the famous
Algorithms, by Robert Sedgewick and Kevin Wayne
book.
On this website, there is this implementation of a red black (balances) tree :
http://algs4.cs.princeton.edu/33balanced/RedBlackBST.java.html
I didnot look into it yet (I will later on this year) , but I fully trust it to be a working implementation of a RBTree.
Some sidenote that might be interesting for visitors of this topic:
MIT placed excellent courses concerning algoritms online. The one concerning rbtrees is
http://www.youtube.com/watch?v=iumaOUqoSCk