728 lines
24 KiB
Java
728 lines
24 KiB
Java
|
/*
|
||
|
* Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved.
|
||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||
|
*
|
||
|
* This code is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License version 2 only, as
|
||
|
* published by the Free Software Foundation.
|
||
|
*
|
||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||
|
* accompanied this code).
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License version
|
||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
|
*
|
||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||
|
* or visit www.oracle.com if you need additional information or have any
|
||
|
* questions.
|
||
|
*/
|
||
|
package jit.graph;
|
||
|
|
||
|
import nsk.share.TestFailure;
|
||
|
|
||
|
//import Node;
|
||
|
|
||
|
// This class defines the tree object.
|
||
|
|
||
|
public class RBTree
|
||
|
{
|
||
|
public final static int maxNodes = 70; // maximum nodes allowed.
|
||
|
public final static int INSERT = 0; // constants indicating
|
||
|
public final static int DELETE = 1; // the current operation
|
||
|
public final static int NOP = 2;
|
||
|
public final static Node treeNull = new Node(); // the tree NULL node.
|
||
|
|
||
|
private Node root;
|
||
|
private int num_of_nodes;
|
||
|
private int height; // The tree heigth ,it is updated
|
||
|
// in each operation.
|
||
|
|
||
|
// since the algorithem is executed in stages I have to remember data
|
||
|
// on the state.
|
||
|
private Node node; // The current operation is being done on it.
|
||
|
private int action;// The operation being performed (insert / delete)
|
||
|
private int stage; // The current stage of execution
|
||
|
|
||
|
// the constructor initialize the object fields.
|
||
|
|
||
|
public RBTree()
|
||
|
{
|
||
|
root = treeNull;
|
||
|
node = treeNull;
|
||
|
num_of_nodes = 0;
|
||
|
height = 0;
|
||
|
action = NOP;
|
||
|
stage = 0;
|
||
|
}
|
||
|
|
||
|
// This method return the root of the tree.
|
||
|
|
||
|
public Node getRoot()
|
||
|
{
|
||
|
return root;
|
||
|
}
|
||
|
|
||
|
// This method return the number of nodes in the tree.
|
||
|
|
||
|
public int getNodes()
|
||
|
{
|
||
|
return num_of_nodes;
|
||
|
}
|
||
|
|
||
|
// This method return the heigth of the tree.
|
||
|
|
||
|
public int getHeight()
|
||
|
{
|
||
|
return height;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
// This method inserts k into the Red Black Tree
|
||
|
|
||
|
public boolean RBInsert(int k)
|
||
|
{
|
||
|
|
||
|
Thread Pause = new Thread(); // this thread is used for delay
|
||
|
// between the stages.
|
||
|
if (action != NOP) // checking similar to the RB_Insert method
|
||
|
{
|
||
|
System.out.println
|
||
|
("Only one operation can be done at a time.");
|
||
|
return false;
|
||
|
}
|
||
|
if (num_of_nodes == maxNodes)
|
||
|
{
|
||
|
System.out.println
|
||
|
("The maximum nodes allowed is already reached.");
|
||
|
return false;
|
||
|
}
|
||
|
if (Search(k) == treeNull) // Check if there is already node with key k.
|
||
|
{
|
||
|
action = INSERT;
|
||
|
node = new Node(k);
|
||
|
node.setNode(Node.Left_son,treeNull);
|
||
|
node.setNode(Node.Right_son,treeNull);
|
||
|
node.setNode(Node.Parent,treeNull);
|
||
|
stage = 1;
|
||
|
while (stage != 0) // This is the loop that perform all the
|
||
|
{ // operation steps.
|
||
|
InsertStep(); // perform one step
|
||
|
updateHeight(); // update the tree height
|
||
|
}
|
||
|
action = NOP; // set the action to NoOPretion.
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
System.out.println
|
||
|
("Insertion failed. This key already exist.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
|
||
|
// This method deletes the element k from the Red Black tree
|
||
|
|
||
|
public boolean RBDelete(int k)
|
||
|
{
|
||
|
Thread Pause = new Thread(); // this thread is used for delay
|
||
|
// between the stages.
|
||
|
if (action != NOP)
|
||
|
{ // checking like in RB_Delete method
|
||
|
System.out.println
|
||
|
("Only one operation can be done at a time.");
|
||
|
return false;
|
||
|
}
|
||
|
node = Search(k);
|
||
|
if (node != treeNull) // Check if there is a node with key k.
|
||
|
{
|
||
|
action = DELETE;
|
||
|
stage = 1;
|
||
|
while (stage != 0) // this loop perform all the operation
|
||
|
{ // steps.
|
||
|
DeleteStep(); // perform one step
|
||
|
updateHeight(); // update the tree height
|
||
|
|
||
|
}
|
||
|
action = NOP;
|
||
|
return true;
|
||
|
}
|
||
|
else
|
||
|
System.out.println
|
||
|
("Deletion failed. This key doesn't exist.");
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
// This method perform one step in the insertion operation.
|
||
|
// If perform a step acording to the stage variable.
|
||
|
// I will not explain exactly what each stage do, just that they
|
||
|
// divided to 4 categories:
|
||
|
// 1. inserting a node to the tree.
|
||
|
// 2. marking nodes that will be recolored.
|
||
|
// 3. recoloring nodes.
|
||
|
// 4. rotating right or left.
|
||
|
|
||
|
private void InsertStep()
|
||
|
{
|
||
|
Node Pr,GrPr,Un; // Pr is parent, GrPr is grandparent
|
||
|
// and Un is uncle.
|
||
|
switch (stage)
|
||
|
{
|
||
|
case 1: // Inserting a node to the tree
|
||
|
/*
|
||
|
System.out.println // send a message to the screen
|
||
|
(new String("Inserting ")
|
||
|
.concat(Integer.toString(node.getKey())));
|
||
|
*/
|
||
|
Tree_Insert(); // inserting an element to the tree
|
||
|
break;
|
||
|
case 2: // mid stage that move to algorithem to the
|
||
|
// proper next stage, and send proper message
|
||
|
// to the screen
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
GrPr = Pr.getNode(Node.Parent);
|
||
|
if (Pr == GrPr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Un = GrPr.getNode(Node.Right_son);
|
||
|
if (Un.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 3;
|
||
|
}
|
||
|
else
|
||
|
if (node == Pr.getNode(Node.Right_son))
|
||
|
{
|
||
|
node = Pr;
|
||
|
stage = 5;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stage = 6;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Un = GrPr.getNode(Node.Left_son);
|
||
|
if (Un.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 3;
|
||
|
}
|
||
|
else
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
node = Pr;
|
||
|
stage = 5;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stage = 6;
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 3: // This stage marks node that will be recolored
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
GrPr = Pr.getNode(Node.Parent);
|
||
|
if (Pr == GrPr.getNode(Node.Left_son))
|
||
|
Un = GrPr.getNode(Node.Right_son);
|
||
|
else
|
||
|
Un = GrPr.getNode(Node.Left_son);
|
||
|
|
||
|
node = GrPr;
|
||
|
stage = 4;
|
||
|
break;
|
||
|
case 4: // this stage recolor marked nodes.
|
||
|
node.setColor(Node.Red);
|
||
|
(node.getNode(Node.Left_son)).setColor(Node.Black);
|
||
|
(node.getNode(Node.Right_son)).setColor(Node.Black);
|
||
|
|
||
|
if ((node == root) ||
|
||
|
((node.getNode(Node.Parent)).getColor() == Node.Black))
|
||
|
if (root.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 9;
|
||
|
}
|
||
|
else
|
||
|
stage = 0;
|
||
|
else
|
||
|
{
|
||
|
stage = 2;
|
||
|
InsertStep();
|
||
|
}
|
||
|
break;
|
||
|
case 5: // This stage perform rotation operation
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
Left_Rotate(node);
|
||
|
else
|
||
|
Right_Rotate(node);
|
||
|
|
||
|
stage = 6;
|
||
|
break;
|
||
|
case 6: // This stage marks nodes that will be recolor.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
GrPr = Pr.getNode(Node.Parent);
|
||
|
|
||
|
stage = 7;
|
||
|
break;
|
||
|
case 7: // This stage recolor marked nodes.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
Pr.setColor(Node.Black);
|
||
|
GrPr = Pr.getNode(Node.Parent);
|
||
|
GrPr.setColor(Node.Red);
|
||
|
|
||
|
stage = 8;
|
||
|
break;
|
||
|
case 8: // This stage perform rotation operation
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
GrPr = Pr.getNode(Node.Parent);
|
||
|
if (Pr == GrPr.getNode(Node.Left_son))
|
||
|
Right_Rotate(GrPr);
|
||
|
else
|
||
|
Left_Rotate(GrPr);
|
||
|
if (root.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 9;
|
||
|
}
|
||
|
else
|
||
|
stage = 0;
|
||
|
break;
|
||
|
case 9: // this stage mark the root.
|
||
|
stage = 10;
|
||
|
break;
|
||
|
case 10: // This stage recolor the root.
|
||
|
root.setColor(Node.Black);
|
||
|
stage = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This method perform one step in the deletion operation.
|
||
|
// If perform a step acording to the stage variable.
|
||
|
// I will explain exactly what each stage do, just that they
|
||
|
// divided to 4 categories:
|
||
|
// 1. deleting a node from the tree.
|
||
|
// 2. marking nodes that will be recolored.
|
||
|
// 3. recoloring nodes.
|
||
|
// 4. rotating right or left.
|
||
|
|
||
|
public void DeleteStep()
|
||
|
{
|
||
|
Node Pr,Br; // Pr is Parent ,Br is Brother
|
||
|
switch (stage)
|
||
|
{
|
||
|
case 1: // This stage delete a node from the tree.
|
||
|
/*
|
||
|
System.out.println
|
||
|
(new String("Deleting ")
|
||
|
.concat(Integer.toString(node.getKey())));
|
||
|
*/
|
||
|
Tree_Delete();
|
||
|
break;
|
||
|
case 2: // This stage marks a nodes that will be recolored
|
||
|
// or perform other stage.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
else
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
if (Br.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 3;
|
||
|
}
|
||
|
else
|
||
|
if (((Br.getNode(Node.Right_son)).getColor() == Node.Black)
|
||
|
&& ((Br.getNode(Node.Left_son)).getColor() == Node.Black))
|
||
|
{
|
||
|
stage = 5;
|
||
|
DeleteStep();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stage = 7;
|
||
|
DeleteStep();
|
||
|
}
|
||
|
break;
|
||
|
case 3: // this stage recolor marked nodes.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
}
|
||
|
Br.setColor(Node.Black);
|
||
|
Pr.setColor(Node.Red);
|
||
|
|
||
|
stage = 4;
|
||
|
break;
|
||
|
case 4: // this stage perform rotation operation
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Left_Rotate(Pr);
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Right_Rotate(Pr);
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
}
|
||
|
if (((Br.getNode(Node.Right_son)).getColor() == Node.Black)
|
||
|
&& ((Br.getNode(Node.Left_son)).getColor() == Node.Black))
|
||
|
stage = 5;
|
||
|
else
|
||
|
stage = 7;
|
||
|
|
||
|
break;
|
||
|
case 5: // this stage marks nodes that will be recolor.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
else
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
|
||
|
stage = 6;
|
||
|
break;
|
||
|
case 6: // This stage recolor marked nodes.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
else
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
Br.setColor(Node.Red);
|
||
|
node = Pr;
|
||
|
|
||
|
if ((node != root) && (node.getColor() == Node.Black))
|
||
|
stage = 2;
|
||
|
else
|
||
|
if (node.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 13;
|
||
|
}
|
||
|
else
|
||
|
stage = 0;
|
||
|
break;
|
||
|
case 7: // this stage marks nodes that will be recolor
|
||
|
// or perform other stage.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
if ((Br.getNode(Node.Right_son)).getColor() == Node.Black)
|
||
|
{
|
||
|
stage = 8;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stage = 10;
|
||
|
DeleteStep();
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
if ((Br.getNode(Node.Left_son)).getColor() == Node.Black)
|
||
|
{
|
||
|
stage = 8;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
stage = 10;
|
||
|
DeleteStep();
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
case 8: // this stage recolor marked nodes.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
(Br.getNode(Node.Left_son)).setColor(Node.Black);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
(Br.getNode(Node.Right_son)).setColor(Node.Black);
|
||
|
|
||
|
}
|
||
|
Br.setColor(Node.Red);
|
||
|
stage = 9;
|
||
|
break;
|
||
|
case 9: // this stage perform rotation operation
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
Right_Rotate(Br);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
Left_Rotate(Br);
|
||
|
}
|
||
|
|
||
|
stage = 10;
|
||
|
break;
|
||
|
case 10: // This stage marks node that will be recolor.
|
||
|
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
}
|
||
|
|
||
|
stage = 11;
|
||
|
break;
|
||
|
case 11: // this stage recolor marked nodes.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Right_son);
|
||
|
(Br.getNode(Node.Right_son)).setColor(Node.Black);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Br = Pr.getNode(Node.Left_son);
|
||
|
(Br.getNode(Node.Left_son)).setColor(Node.Black);
|
||
|
|
||
|
}
|
||
|
if (Br.getColor() != Pr.getColor())
|
||
|
Br.setColor(Pr.getColor());
|
||
|
if (Pr.getColor() != Node.Black)
|
||
|
Pr.setColor(Node.Black);
|
||
|
|
||
|
stage = 12;
|
||
|
break;
|
||
|
case 12: // this stage perform rotation operation.
|
||
|
Pr = node.getNode(Node.Parent);
|
||
|
if (node == Pr.getNode(Node.Left_son))
|
||
|
Left_Rotate(Pr);
|
||
|
else
|
||
|
Right_Rotate(Pr);
|
||
|
node = root;
|
||
|
if (node.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 13;
|
||
|
}
|
||
|
else
|
||
|
stage = 0;
|
||
|
break;
|
||
|
case 13: // this stage marks a node that will be recolor
|
||
|
stage = 14;
|
||
|
break;
|
||
|
case 14: // this stage recolor marked node.
|
||
|
node.setColor(Node.Black);
|
||
|
stage = 0;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// This method insert the node 'node' to the tree.
|
||
|
// it called from the first stage in the InsertStep method.
|
||
|
// we 'dive' from the root to a leaf acording to the node key
|
||
|
// and insert the node in the proper place.
|
||
|
|
||
|
private void Tree_Insert()
|
||
|
{
|
||
|
Node n1,n2;
|
||
|
n1 = root;
|
||
|
n2 = treeNull;
|
||
|
while (n1 != treeNull)
|
||
|
{
|
||
|
n2 = n1;
|
||
|
if (node.getKey() < n1.getKey())
|
||
|
n1 = n1.getNode(Node.Left_son);
|
||
|
else
|
||
|
n1 = n1.getNode(Node.Right_son);
|
||
|
}
|
||
|
node.setNode(Node.Parent,n2);
|
||
|
if (n2 == treeNull)
|
||
|
root = node;
|
||
|
else
|
||
|
{
|
||
|
if (node.getKey() < n2.getKey())
|
||
|
n2.setNode(Node.Left_son,node);
|
||
|
else
|
||
|
n2.setNode(Node.Right_son,node);
|
||
|
}
|
||
|
//Parent.display.drawTree();
|
||
|
// updating the insertion stage.
|
||
|
if ((node == root) ||
|
||
|
((node.getNode(Node.Parent)).getColor() == Node.Black))
|
||
|
if (root.getColor() == Node.Red)
|
||
|
{
|
||
|
stage = 9;
|
||
|
}
|
||
|
else
|
||
|
stage = 0;
|
||
|
else
|
||
|
{
|
||
|
stage = 2;
|
||
|
InsertStep();
|
||
|
}
|
||
|
num_of_nodes++; // increasing the number of nodes
|
||
|
}
|
||
|
|
||
|
// This method delete the node 'node' from the tree.
|
||
|
// it called from the first stage in the DeleteStep method.
|
||
|
// if node has at most one son we just remove it and connect
|
||
|
// his son and parent. If it has 2 sons we delete his successor
|
||
|
// that has at most one son and replace him with the successor.
|
||
|
|
||
|
private void Tree_Delete()
|
||
|
{
|
||
|
Node n1,n2,n3;
|
||
|
if ((node.getNode(Node.Left_son) == treeNull) ||
|
||
|
(node.getNode(Node.Right_son) == treeNull))
|
||
|
n1 = node;
|
||
|
else
|
||
|
n1 = Tree_Successor(node);
|
||
|
if (n1.getNode(node.Left_son) != treeNull)
|
||
|
n2 = n1.getNode(Node.Left_son);
|
||
|
else
|
||
|
n2 = n1.getNode(Node.Right_son);
|
||
|
|
||
|
n3 = n1.getNode(Node.Parent);
|
||
|
n2.setNode(Node.Parent,n3);
|
||
|
if (n3 == treeNull)
|
||
|
root = n2;
|
||
|
else
|
||
|
if (n1 == n3.getNode(Node.Left_son))
|
||
|
n3.setNode(Node.Left_son,n2);
|
||
|
else
|
||
|
n3.setNode(Node.Right_son,n2);
|
||
|
|
||
|
if (n1 != node)
|
||
|
{
|
||
|
node.setKey(n1.getKey());
|
||
|
}
|
||
|
|
||
|
|
||
|
node = n2;
|
||
|
if (n1.getColor() == Node.Black)
|
||
|
if ((node != root) && (node.getColor() == Node.Black))
|
||
|
stage = 2;
|
||
|
else
|
||
|
if (node.getColor() == Node.Red)
|
||
|
stage = 13;
|
||
|
else
|
||
|
stage = 0;
|
||
|
else
|
||
|
stage = 0;
|
||
|
num_of_nodes--; // decrease the number of nodes.
|
||
|
}
|
||
|
|
||
|
// This method return the successor of the node n in the tree.
|
||
|
|
||
|
private Node Tree_Successor(Node n)
|
||
|
{
|
||
|
Node n1;
|
||
|
if (n.getNode(Node.Right_son) != treeNull)
|
||
|
{
|
||
|
n = n.getNode(Node.Right_son);
|
||
|
while (n.getNode(Node.Left_son) != treeNull)
|
||
|
n = n.getNode(Node.Left_son);
|
||
|
return n;
|
||
|
}
|
||
|
n1 = n.getNode(Node.Parent);
|
||
|
while ((n1 != treeNull) && (n == n1.getNode(Node.Right_son)))
|
||
|
{
|
||
|
n = n1;
|
||
|
n1 = n1.getNode(Node.Parent);
|
||
|
}
|
||
|
return n1;
|
||
|
}
|
||
|
|
||
|
// This method perform Left Rotation with n1.
|
||
|
|
||
|
private void Left_Rotate(Node n1)
|
||
|
{
|
||
|
Node n2;
|
||
|
|
||
|
n2 = n1.getNode(Node.Right_son);
|
||
|
n1.setNode(Node.Right_son,n2.getNode(Node.Left_son));
|
||
|
if (n2.getNode(Node.Left_son) != treeNull)
|
||
|
(n2.getNode(Node.Left_son)).setNode(Node.Parent,n1);
|
||
|
n2.setNode(Node.Parent,n1.getNode(Node.Parent));
|
||
|
if (n1.getNode(Node.Parent) == treeNull)
|
||
|
root = n2;
|
||
|
else
|
||
|
if (n1 == (n1.getNode(Node.Parent)).getNode(Node.Left_son))
|
||
|
(n1.getNode(Node.Parent)).setNode(Node.Left_son,n2);
|
||
|
else
|
||
|
(n1.getNode(Node.Parent)).setNode(Node.Right_son,n2);
|
||
|
n2.setNode(Node.Left_son,n1);
|
||
|
n1.setNode(Node.Parent,n2);
|
||
|
}
|
||
|
|
||
|
// This method perform Right Rotation with n1.
|
||
|
|
||
|
private void Right_Rotate(Node n1)
|
||
|
{
|
||
|
Node n2;
|
||
|
|
||
|
n2 = n1.getNode(Node.Left_son);
|
||
|
n1.setNode(Node.Left_son,n2.getNode(Node.Right_son));
|
||
|
if (n2.getNode(Node.Right_son) != treeNull)
|
||
|
(n2.getNode(Node.Right_son)).setNode(Node.Parent,n1);
|
||
|
n2.setNode(Node.Parent,n1.getNode(Node.Parent));
|
||
|
if (n1.getNode(Node.Parent) == treeNull)
|
||
|
root = n2;
|
||
|
else
|
||
|
if (n1 == (n1.getNode(Node.Parent)).getNode(Node.Left_son))
|
||
|
(n1.getNode(Node.Parent)).setNode(Node.Left_son,n2);
|
||
|
else
|
||
|
(n1.getNode(Node.Parent)).setNode(Node.Right_son,n2);
|
||
|
n2.setNode(Node.Right_son,n1);
|
||
|
n1.setNode(Node.Parent,n2);
|
||
|
}
|
||
|
|
||
|
// This method search the tree for a node with key 'key', and
|
||
|
// return the node on success otherwise treeNull.
|
||
|
|
||
|
public Node Search(int key)
|
||
|
{
|
||
|
Node node;
|
||
|
node = root;
|
||
|
while ((node != treeNull) && (key != node.getKey()))
|
||
|
if (key < node.getKey())
|
||
|
node = node.getNode(Node.Left_son);
|
||
|
else
|
||
|
node = node.getNode(Node.Right_son);
|
||
|
return node;
|
||
|
}
|
||
|
|
||
|
// This method update the tree height it uses a recursive method
|
||
|
// findheight.
|
||
|
|
||
|
private void updateHeight()
|
||
|
{
|
||
|
height = 0;
|
||
|
if (root != treeNull)
|
||
|
findHeight(root,1);
|
||
|
}
|
||
|
|
||
|
// This is a recursive method that find a node height.
|
||
|
|
||
|
private void findHeight(Node n,int curr)
|
||
|
{
|
||
|
if (height < curr)
|
||
|
height = curr;
|
||
|
if (n.getNode(Node.Left_son) != treeNull)
|
||
|
findHeight(n.getNode(Node.Left_son),curr+1);
|
||
|
if (n.getNode(Node.Right_son) != treeNull)
|
||
|
findHeight(n.getNode(Node.Right_son),curr+1);
|
||
|
}
|
||
|
|
||
|
}
|