Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openjdk/test/hotspot/jtreg/vmTestbase/jit/graph/   (Sun/Oracle ©)  Datei vom 13.11.2022 mit Größe 22 kB image not shown  

Quelle  RBTree.java   Sprache: JAVA

 
/*
 * 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.
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 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.
    private int action; // The operation being performed (insert / delete)
    private int 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.
    public int getNodes() {
        return num_of_nodes;
    }

    // This method returns the height of the tree.
    public int getHeight() {
        return height;
    }


    // This method inserts k into the Red Black Tree
    public boolean 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.");
            return false;
        }

        if (num_of_nodes == maxNodes) {
            System.out.println("The maximum nodes allowed is already reached.");
            return false;
        }

        // 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;
            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) {
        // checking like in RB_Delete method
        if (action != NOP) {
            System.out.println("Only one operation can be done at a time.");
            return false;
        }
        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;
            return true;
        } else
            System.out.println("Deletion failed. This key doesn't exist.");
        return false;
    }

    // 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.
    private void 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;
                    } 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;
            // 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.
    public void 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;
                } 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;
            // 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);

                stage = 4;
                break;
            // This stage performs rotation operation
            case 4:
                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;
            // 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;
                } else if (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);
                }

                stage = 11;
                break;
            // This stage recolors marked nodes.
            case 11:
                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;
            // 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.
    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);
            }
        }
        // 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.
    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;
        }
        // decrease the number of nodes.
        num_of_nodes--;
    }

    // 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.
    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 performs 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 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.
    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);
        }
    }

}

Messung V0.5
C=90 H=95 G=92

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.