Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

Student Name: UID:

WS9
Write a program to implement insert and delete node in a Red-Black tree.

1. Aim/Overview of the practical:


Write a program to implement insert and delete node in a Red black
tree

2. Algorithm/Flowchart (For programming based labs):

3.code

insertion:-

package com.practice;

public class RedBlackTree


{
public Node root;//root node public RedBlackTree()
{
super(); root = null;
}
// node creating sublass class Node
{
int data; Node left; Node right; char colour; Node parent;

Node(int data)
{
super();
this.data = data; // only including data. not key this.left = null; // left subtree
this.right = null; // right subtree
this.colour = 'R'; // colour . either 'R' or 'B' this.parent = null; // required at time of
rechecking.
}
}
// this function performs left rotation Node rotateLeft(Node node)
{
Node x = node.right; Node y = x.left;

x.left = node; node.right = y;


node.parent = x; // parent resetting is also important. if(y!=null)
y.parent = node; return(x);
}
//this function performs right rotation Node rotateRight(Node node)
{
Node x = node.left; Node y = x.right; x.right = node; node.left = y; node.parent = x;
if(y!=null)
y.parent = node; return(x);
}

// these are some flags.


// Respective rotations are performed during traceback.
// rotations are done if flags are true. boolean ll = false;
boolean rr = false; boolean lr = false; boolean rl = false;
// helper function for insertion. Actually this function performs all tasks in single pass
only.
Node insertHelp(Node root, int data)
{
// f is true when RED RED conflict is there. boolean f=false;
//recursive calls to insert at proper position according to BST properties.
if(root==null)
return(new Node(data)); else if(data<root.data)
{
root.left = insertHelp(root.left, data); root.left.parent = root;

if(root!=this.root)
{

}
}
else
{

if(root.colour=='R' && root.left.colour=='R') f = true;

root.right = insertHelp(root.right,data); root.right.parent = root; if(root!=this.root)


{
if(root.colour=='R' && root.right.colour=='R') f = true;
}
// at the same time of insertion, we are also assigning parent nodes
// also we are checking for RED RED conflicts
}

// now lets rotate. if(this.ll) // for left rotate.


{
root = rotateLeft(root); root.colour = 'B'; root.left.colour = 'R'; this.ll = false;
}
else if(this.rr) // for right rotate
{
root = rotateRight(root); root.colour = 'B'; root.right.colour = 'R'; this.rr = false;
}
else if(this.rl) // for right and then left
{
root.right = rotateRight(root.right); root.right.parent = root;
root = rotateLeft(root); root.colour = 'B'; root.left.colour = 'R';

this.rl = false;
}
else if(this.lr) // for left and then right.
{
root.left = rotateLeft(root.left); root.left.parent = root;
root = rotateRight(root);
root.colour = 'B'; root.right.colour = 'R'; this.lr = false;
}
// when rotation and recolouring is done flags are reset.
// Now lets take care of RED RED conflict if(f)
{

parent

if(root.parent.right == root) // to check which child is the current node of its

{
if(root.parent.left==null || root.parent.left.colour=='B') // case when

parent's sibling is black


{// perform certaing rotation and recolouring. This will be done while backtracking.
Hence setting up respective flags.
if(root.left!=null && root.left.colour=='R') this.rl = true;
else if(root.right!=null && root.right.colour=='R') this.ll = true;
}
else // case when parent's sibling is red
{

}
}
else
{

root.parent.left.colour = 'B'; root.colour = 'B'; if(root.parent!=this.root)


root.parent.colour = 'R';

if(root.parent.right==null || root.parent.right.colour=='B')
{
if(root.left!=null && root.left.colour=='R') this.rr = true;
else if(root.right!=null && root.right.colour=='R')

}
else
{

}
}

this.lr = true;
root.parent.right.colour = 'B'; root.colour = 'B'; if(root.parent!=this.root)
root.parent.colour = 'R';

f = false;
}
return(root);
}

// function to insert data into tree. public void insert(int data)


{
if(this.root==null)
{

}
else

this.root = new Node(data); this.root.colour = 'B';

this.root = insertHelp(this.root,data);

// helper function to print inorder traversal void inorderTraversalHelper(Node node)


{
if(node!=null)
{
inorderTraversalHelper(node.left); System.out.printf("%d ", node.data);
inorderTraversalHelper(node.right);
}
}
//function to print inorder traversal public void inorderTraversal()
{
inorderTraversalHelper(this.root);
}
// helper function to print the tree.

void printTreeHelper(Node root, int space)


{
int i;
if(root != null)
{
space = space + 10; printTreeHelper(root.right, space); System.out.printf("\n");
for ( i = 10; i < space; i++)
{
System.out.printf(" ");
}
System.out.printf("%d", root.data); System.out.printf("\n"); printTreeHelper(root.left,
space);
}
}
// function to print the tree. public void printTree()
{
printTreeHelper(this.root, 0);
}
public static void main(String[] args)
{
// let us try to insert some data into tree and try to visualize the tree as well as
traverse.
RedBlackTree t = new RedBlackTree();
int[] arr = {1,4,6,3,5,7,8,2,9};
for(int i=0;i<9;i++)
{
t.insert(arr[i]); System.out.println(); t.inorderTraversal();
}
// you can check colour of any node by with its attribute node.colour t.printTree();
}

for deletion:-

package com.company;

enum Color {
Red, Black
}

class TreeNode { public int data;


public TreeNode right; public TreeNode left; public TreeNode parent; public Color
color;

public TreeNode(int data) { this.left = null; this.right = null; this.parent = null; this.data
= data; this.color = Color.Red;
}
}

class RBTree { TreeNode root; TreeNode NIL;

public RBTree() {
TreeNode nilNode = new TreeNode(0); nilNode.color = Color.Black; this.NIL =
nilNode;
this.root = this.NIL;
}

public void leftRotate(TreeNode x) { TreeNode y = x.right;


x.right = y.left; if(y.left != this.NIL) {
y.left.parent = x;
}
y.parent = x.parent;
if(x.parent == this.NIL) { //x is root this.root = y;
}
else if(x == x.parent.left) { //x is left child x.parent.left = y;
}
else { //x is right child x.parent.right = y;
}

y.left = x; x.parent = y;
}

public void rightRotate(TreeNode x) { TreeNode y = x.left;


x.left = y.right; if(y.right != this.NIL) {
y.right.parent = x;
}
y.parent = x.parent;
if(x.parent == this.NIL) { //x is root this.root = y;
}
else if(x == x.parent.right) { //x is left child x.parent.right = y;
}
else { //x is right child x.parent.left = y;
}
y.right = x; x.parent = y;
}

public void insertFixup(TreeNode z) { while(z.parent.color == Color.Red) {


if(z.parent == z.parent.parent.left) { //z.parent is the left child

TreeNode y = z.parent.parent.right; //uncle of z

if(y.color == Color.Red) { //case 1 z.parent.color = Color.Black; y.color =


Color.Black; z.parent.parent.color = Color.Red; z = z.parent.parent;
}
else { //case2 or case3
if(z == z.parent.right) { //case2
z = z.parent; //marked z.parent as new z leftRotate(z);
}
//case3
z.parent.color = Color.Black; //made parent black z.parent.parent.color =
Color.Red; //made parent red rightRotate(z.parent.parent);
}
}

else { //z.parent is the right child


TreeNode y = z.parent.parent.left; //uncle of z

if(y.color == Color.Red) { z.parent.color = Color.Black; y.color = Color.Black;


z.parent.parent.color = Color.Red; z = z.parent.parent;
}
else {
if(z == z.parent.left) {
z = z.parent; //marked z.parent as new z rightRotate(z);
}
z.parent.color = Color.Black; //made parent black z.parent.parent.color =
Color.Red; //made parent red leftRotate(z.parent.parent);
}
}
}
this.root.color = Color.Black;
}

public void insert(TreeNode z) {


TreeNode y = this.NIL; //variable for the parent of the added node TreeNode temp =
this.root;
while(temp != this.NIL) { y = temp;
if(z.data < temp.data) temp = temp.left;

else

temp = temp.right;

z.parent = y;

if(y == this.NIL) { //newly added node is root this.root = z;


}
else if(z.data < y.data) //data of child is less than its parent, left child y.left = z;
else
y.right = z;

z.right = this.NIL; z.left = this.NIL;

insertFixup(z);
}

public void rbTransplant(TreeNode u, TreeNode v) { if(u.parent == this.NIL)


this.root = v;
else if(u == u.parent.left) u.parent.left = v;
else
u.parent.right = v;
v.parent = u.parent;
}

public TreeNode minimum(TreeNode x) { while(x.left != this.NIL)


x = x.left;
return x;
}

public void deleteFixup(TreeNode x) {


while(x != this.root && x.color == Color.Black) { if(x == x.parent.left) {
TreeNode w = x.parent.right; if(w.color == Color.Red) {
w.color = Color.Black; x.parent.color = Color.Red; leftRotate(x.parent);
w = x.parent.right;
}
if(w.left.color == Color.Black && w.right.color == Color.Black) { w.color =
Color.Red;
x = x.parent;
}
else {
if(w.right.color == Color.Black) { w.left.color = Color.Black; w.color = Color.Red;
rightRotate(w);
w = x.parent.right;
}
w.color = x.parent.color; x.parent.color = Color.Black; w.right.color = Color.Black;
leftRotate(x.parent);
x = this.root;
}
}

else {
TreeNode w = x.parent.left; if(w.color == Color.Red) {
w.color = Color.Black;
x.parent.color = Color.Red; rightRotate(x.parent);
w = x.parent.left;
}
if(w.right.color == Color.Black && w.left.color == Color.Black) { w.color =
Color.Red;
x = x.parent;
}
else {
if(w.left.color == Color.Black) { w.right.color = Color.Black; w.color = Color.Red;
leftRotate(w);
w = x.parent.left;
}
w.color = x.parent.color; x.parent.color = Color.Black; w.left.color = Color.Black;
rightRotate(x.parent);
x = this.root;
}
}
}
x.color = Color.Black;
}

public void rbDelete(TreeNode z) { TreeNode y = z;


TreeNode x;
Color yOrignalColor = y.color; if(z.left == this.NIL) {
x = z.right;
rbTransplant(z, z.right);
}
else if(z.right == this.NIL) { x = z.left; rbTransplant(z, z.left);
}

else {
y = minimum(z.right); yOrignalColor = y.color;

x = y.right; if(y.parent == z) {
x.parent = z;
}
else {
rbTransplant(y, y.right); y.right = z.right; y.right.parent = y;
}
rbTransplant(z, y); y.left = z.left; y.left.parent = y; y.color = z.color;
}
if(yOrignalColor == Color.Black) deleteFixup(x);
}

public void inorder(TreeNode n) {


if (n != this.NIL) {

inorder(n.left); System.out.println(n.data); inorder(n.right);


}
}

public static void main(String[] args){

RBTree t = new RBTree();

TreeNode a, b, c, d, e, f, g, h, i, j, k, l, m;

a = new TreeNode(10);
b = new TreeNode(20);
c = new TreeNode(30);
d = new TreeNode(100);
e = new TreeNode(90);
f = new TreeNode(40);
g = new TreeNode(50);
h = new TreeNode(60);
i = new TreeNode(70);
j = new TreeNode(80);
k = new TreeNode(150);
l = new TreeNode(110);
m = new TreeNode(120);

t.insert(a);
t.insert(b);
t.insert(c);

}
7. Result/Output/
For deletion:-

You might also like