/* * Copyright (c) 2008, 2019, 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;
// This class defines the tree object. publicclass RBTree { publicfinalstaticint maxNodes = 70; // maximum nodes allowed. publicfinalstaticint INSERT = 0; // constants indicating publicfinalstaticintDELETE = 1; // the current operation publicfinalstaticint NOP = 2; publicfinalstatic Node treeNull = new Node(); // the tree NULL node.
private Node root; privateint num_of_nodes; privateint height; // The tree height, it is updated // in each operation.
// since the algorithm is executed in stages I have to remember data // on the state. private Node node; // The current operation is being done on it. privateint action; // The operation being performed (insert / delete) privateint stage; // The current stage of execution
// the constructor initializes the object fields. public RBTree() {
root = treeNull;
node = treeNull;
num_of_nodes = 0;
height = 0;
action = NOP;
stage = 0;
}
// This method returns the root of the tree. public Node getRoot() { return root;
}
// This method returns the number of nodes in the tree. publicint getNodes() { return num_of_nodes;
}
// This method returns the height of the tree. publicint getHeight() { return height;
}
// This method inserts k into the Red Black Tree publicboolean RBInsert(int k) { // checking similar to the RB_Insert method if (action != NOP) {
System.out.println("Only one operation can be done at a time."); returnfalse;
}
if (num_of_nodes == maxNodes) {
System.out.println("The maximum nodes allowed is already reached."); returnfalse;
}
// Check if there is already node with key k. if (Search(k) == treeNull) {
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; // This is the loop that perform all the operation steps. while (stage != 0) { // perform one step
InsertStep(); // update the tree height
updateHeight();
} // set the action to NoOPretion.
action = NOP; returntrue;
} else
System.out.println("Insertion failed. This key already exist."); returnfalse;
}
// This method deletes the element k from the Red Black tree publicboolean RBDelete(int k) { // checking like in RB_Delete method if (action != NOP) {
System.out.println("Only one operation can be done at a time."); returnfalse;
}
node = Search(k); // Check if there is a node with key k. if (node != treeNull) {
action = DELETE;
stage = 1; // this loop perform all the operation steps. while (stage != 0) { // perform one step
DeleteStep(); // update the tree height
updateHeight();
}
action = NOP; returntrue;
} else
System.out.println("Deletion failed. This key doesn't exist."); returnfalse;
}
// This method performs one step in the insertion operation. // It performs a step according 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. privatevoid InsertStep() { // Pr is parent, GrPr is grandparent and Un is uncle.
Node Pr, GrPr, Un; switch (stage) { // Inserting a node to the tree case 1:
Tree_Insert(); break; // mid stage that moves the algorithm to the proper next stage case 2:
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;
} elseif (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;
} elseif (node == Pr.getNode(Node.Left_son)) {
node = Pr;
stage = 5;
} else {
stage = 6;
}
} break; // This stage marks node that will be recolored case 3:
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; // This stage recolors marked nodes. case 4:
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; // This stage performs rotation operation case 5:
Pr = node.getNode(Node.Parent); if (node == Pr.getNode(Node.Left_son)) {
Left_Rotate(node);
} else {
Right_Rotate(node);
}
stage = 6; break; // This stage marks nodes that will be recolor. case 6:
Pr = node.getNode(Node.Parent);
GrPr = Pr.getNode(Node.Parent);
stage = 7; break; // This stage recolors marked nodes. case 7:
Pr = node.getNode(Node.Parent);
Pr.setColor(Node.Black);
GrPr = Pr.getNode(Node.Parent);
GrPr.setColor(Node.Red);
stage = 8; break; // This stage performs rotation operation case 8:
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; // this stage marks the root. case 9:
stage = 10; break; // This stage recolors the root. case 10:
root.setColor(Node.Black);
stage = 0; break;
}
}
// This method performs one step in the deletion operation. // It perform sa step according 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. publicvoid DeleteStep() { // Pr is Parent, Br is Brother
Node Pr, Br; switch (stage) { // This stage delete a node from the tree. case 1:
Tree_Delete(); break; // This stage marks a nodes that will be recolored or perform other stage. case 2:
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;
} elseif ((Br.getNode(Node.Right_son).getColor() == Node.Black)
&& (Br.getNode(Node.Left_son).getColor() == Node.Black)) {
stage = 5;
DeleteStep();
} else {
stage = 7;
DeleteStep();
} break; // This stage recolors marked nodes. case 3:
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);
break; // This stage marks nodes that will be recolor. case 5:
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; // This stage recolors marked nodes. case 6:
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;
} elseif (node.getColor() == Node.Red) {
stage = 13;
} else
stage = 0; break; // This stage marks nodes that will be recolor or perform other stage. case 7:
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; // This stage recolors marked nodes. case 8:
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; // This stage performs rotation operation case 9:
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; // This stage marks node that will be recolor. case 10:
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() != Pr.getColor()) {
Br.setColor(Pr.getColor());
} if (Pr.getColor() != Node.Black) {
Pr.setColor(Node.Black);
}
stage = 12; break; // This stage performs rotation operation. case 12:
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; // This stage marks a node that will be recolored case 13:
stage = 14; break; // This stage recolors marked node. case 14:
node.setColor(Node.Black);
stage = 0; break;
}
}
// This method inserts the node 'node' to the tree. // it called from the first stage in the InsertStep method. // we 'dive' from the root to a leaf according to the node key // and insert the node in the proper place. privatevoid 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);
}
} // 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 deletes 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. privatevoid 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);
}
// This method returns 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 performs Left Rotation with n1. privatevoid Left_Rotate(Node n1) {
Node n2;
// This method searches the tree for a node with key 'key', and // returns 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 updates the tree height. it uses a recursive method // findHeight. privatevoid updateHeight() {
height = 0; if (root != treeNull) {
findHeight(root, 1);
}
}
// This is a recursive method that find a node height. privatevoid 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);
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.