Example #1
0
        // Function to add node to the tree.The add function is from psuedocode on page 315 of CRLS
        //input: this is calling object, the RedBlack tree itself. z is a new Redblack Tree node to be inserted into this
        //output: Z node is added to the tree, size is added and the new height of the tree calculated
        public void add(RedBlackNode z)
        {
            RedBlackNode y = new RedBlackNode();
            y = this.nil;
            RedBlackNode x = new RedBlackNode();
            x = this.root;

            //go until you hit a leaf node and insert at bottom of tree if you do
            while (x != this.nil)
            {
                //keeping track of previvous parent
                y = x;

                //going down the left or right sub tree
                if (z.Data < x.Data)
                {
                    x = x.Left;
                }
                else
                {
                    x = x.Right;
                }
            }

            //after exiting the while loop we have figured out where to place
            //node z and y is his parent.
            z.Parent = y;

            //if y was nil, then z is the root.
            if (y == this.nil)
            {
                this.root = z;
            }//less than y than it goes left of y
            else if(z.Data < y.Data)
            {
                y.Left = z;
            }
            else
            {
                y.Right = z;
            }

            //Setting everthing for z
            z.Left = this.nil;
            z.Right = this.nil;
            z.Color = RedBlackNode.RED;

            treeSize = treeSize + 1;

            //fixing the redblack colors of the nodes in the tree
            //Console.WriteLine("Inserted " + z.Data);
            this.InsertFixup(z);
        }
Example #2
0
 // defualt constructor for a Redblack tree
 public RedBlack()
 {
     treeSize = 0;
     height = 0;
     nil = new RedBlackNode();
     nil.Left = null;
     nil.Right = null;
     nil.Data = -1;
     nil.Parent = null;
     nil.Size = 0;
     nil.Color = RedBlackNode.BLACK;
     root = nil;
 }
Example #3
0
        static void Main(string[] args)
        {
            Console.Write("What is full path to the data file?");
            string data = Console.ReadLine();

            Console.WriteLine("Expecting the file to be tab delimited, so key\toperation for each line");
            Console.Write("What is full path to the DynamicOps file?");
            string dofile = Console.ReadLine();

            RedBlack tree = new RedBlack(); //tree to hold all the nodes

            string date = DateTime.Now.Ticks.ToString();
            string reportName = "report" + date + ".txt";

            Console.WriteLine("name of the report file: " + reportName );
            TextWriter report = new StreamWriter(reportName); //file to write out the report

            int counter = 0; //count the lines in the file
            string line; // line in the file

            // Read the file and add the node line by line.
            try
            {
                System.IO.StreamReader file = new System.IO.StreamReader(data);

                while ((line = file.ReadLine()) != null)
                {
                    RedBlackNode x = new RedBlackNode();
                    x.Data = Convert.ToInt32(line);     // line comes in as a string, converting to a int to add to the node
                    tree.add(x);                        //adding the node to the tree

                    if (counter % 1000 == 0) { Console.WriteLine("Adding node " + counter); } // letting you know something is going on...it takes a long time to add nodes and calculate their size of the subtree

                    if (counter == 100)
                    {
                        Console.WriteLine("The height of the tree is after 100 inserts " + tree.Height());
                        report.WriteLine("The height of the tree is after 100 inserts " + tree.Height());
                    }
                    if (counter == 1000)
                    {
                        Console.WriteLine("The height of the tree is after 1000 inserts " + tree.Height());
                        report.WriteLine("The height of the tree is after 1000 inserts " + tree.Height());
                    }

                    counter++;
                }

                file.Close();   //closing the file like a good programmer

                ///*
                // * All the operations as asked from the original data set
                // * Find the 10 integers in the original data set with the following percentiles:  45 86 85 39 63 76 68 95 5  96.
                // * Also find the rankings in percentile of the following 10 integers using the original data set:
                // * 12858       46144       17350       17043       35198       62194        5913       18535       57524       23484.
                // * */

                Console.WriteLine();
                Console.WriteLine();

                Console.WriteLine("Tree size " + tree.returnTreeSize());        //normal tree size, just adding the nodes as insert
                Console.WriteLine("Calculated Tree size " + tree.size());              //tracks the nodes size of the subtree
                Console.WriteLine("Tree min value " + tree.minimum().Data);     //the minimum node in the tree
                Console.WriteLine("Tree max value " + tree.maximum().Data);     //the max node in the tree
                Console.WriteLine("tree height " + tree.Height());              // the height of the tree with the original data set
                Console.WriteLine("tree root : " + tree.returnRoot().Data);     //the root of the tree

                report.WriteLine("Tree size " + tree.returnTreeSize());        //normal tree size, just adding the nodes as insert
                report.WriteLine("Calculated Tree size " + tree.size());              //tracks the nodes size of the subtree
                report.WriteLine("Tree min value " + tree.minimum().Data);     //the minimum node in the tree
                report.WriteLine("Tree max value " + tree.maximum().Data);     //the max node in the tree
                report.WriteLine("tree height " + tree.Height());              // the height of the tree with the original data set
                report.WriteLine("tree root : " + tree.returnRoot().Data);     //the root of the tree

                //uncommit this if you want the tree to be printed out in preorder traversal
                // tree.PreOrder();

                Console.WriteLine();
                Console.WriteLine();

                //getting the nodes at the percentiles asked for
                Console.WriteLine("45 percentile: " + tree.orderSelect(45).Data);
                Console.WriteLine("86 percentile: " + tree.orderSelect(86).Data);
                Console.WriteLine("85 percentile: " + tree.orderSelect(85).Data);
                Console.WriteLine("39 percentile: " + tree.orderSelect(39).Data);
                Console.WriteLine("63 percentile: " + tree.orderSelect(63).Data);
                Console.WriteLine("76 percentile: " + tree.orderSelect(76).Data);
                Console.WriteLine("68 percentile: " + tree.orderSelect(68).Data);
                Console.WriteLine("95 percentile: " + tree.orderSelect(95).Data);
                Console.WriteLine("5 percentile: " + tree.orderSelect(5).Data);
                Console.WriteLine("96 percentile: " + tree.orderSelect(50).Data);

                report.WriteLine("45 percentile: " + tree.orderSelect(45).Data);
                report.WriteLine("86 percentile: " + tree.orderSelect(86).Data);
                report.WriteLine("85 percentile: " + tree.orderSelect(85).Data);
                report.WriteLine("39 percentile: " + tree.orderSelect(39).Data);
                report.WriteLine("63 percentile: " + tree.orderSelect(63).Data);
                report.WriteLine("76 percentile: " + tree.orderSelect(76).Data);
                report.WriteLine("68 percentile: " + tree.orderSelect(68).Data);
                report.WriteLine("95 percentile: " + tree.orderSelect(95).Data);
                report.WriteLine("5 percentile: " + tree.orderSelect(5).Data);
                report.WriteLine("96 percentile: " + tree.orderSelect(50).Data);

                //in order to find the rank of the node we have to find the node first and then do the calculation
                //if a -1 is return the node was not find in the tree....

                Console.WriteLine();
                Console.WriteLine();
                report.WriteLine();
                report.WriteLine();

                RedBlackNode search = new RedBlackNode();
                search = tree.search(12858);
                Console.WriteLine("12858 rank is: " + tree.osRank(search));
                report.WriteLine("12858 rank is: " + tree.osRank(search));
                search = tree.search(46144);
                Console.WriteLine("46144 rank is: " + tree.osRank(search));
                report.WriteLine("46144 rank is: " + tree.osRank(search));
                search = tree.search(17350);
                Console.WriteLine("17350 rank is: " + tree.osRank(search));
                report.WriteLine("17350 rank is: " + tree.osRank(search));
                search = tree.search(17043);
                Console.WriteLine("17043 rank is: " + tree.osRank(search));
                report.WriteLine("17043 rank is: " + tree.osRank(search));
                search = tree.search(35198);
                Console.WriteLine("35198 rank is: " + tree.osRank(search));
                report.WriteLine("35198 rank is: " + tree.osRank(search));
                search = tree.search(62194);
                Console.WriteLine("62194 rank is: " + tree.osRank(search));
                report.WriteLine("62194 rank is: " + tree.osRank(search));
                search = tree.search(5913);
                Console.WriteLine("5913 rank is: " + tree.osRank(search));
                report.WriteLine("5913 rank is: " + tree.osRank(search));
                search = tree.search(18535);
                Console.WriteLine("18535 rank is: " + tree.osRank(search));
                report.WriteLine("18535 rank is: " + tree.osRank(search));
                search = tree.search(57524);
                Console.WriteLine("57524 rank is: " + tree.osRank(search));
                report.WriteLine("57524 rank is: " + tree.osRank(search));
                search = tree.search(23484);
                Console.WriteLine("23484 rank is: " + tree.osRank(search));
                report.WriteLine("23484 rank is: " + tree.osRank(search));

                //variables to add or delete the node in the DynamicOps file
                char[] delimiters = { '\t' }; // Program expects the data in key\toperation where key is the data of the node to be operated on, and operations is a 1 (add) or 0 (delete),
                string[] words; // string array that will contain the the key at words[0] and the operation at words[1]
                int key = -1;
                int operation = -1;

                Console.WriteLine();
                Console.WriteLine();

                counter = 0;

                System.IO.StreamReader DynamicOps = new System.IO.StreamReader(dofile);
                while ((line = DynamicOps.ReadLine()) != null)
                {
                    RedBlackNode node = new RedBlackNode();
                    words = line.Split(delimiters);
                    key = Convert.ToInt32(words[0]);
                    operation = Convert.ToInt32(words[1]);
                    node.Data = key;

                    if (operation == 0) //delete the key if operation is a 0
                    {
                        Console.WriteLine("Deleting node " + node.Data);
                        report.WriteLine("Deleting node " + node.Data);
                        node = tree.search(key);
                        if (node.Data == -1)
                        {
                            Console.WriteLine("Node was not found in the tree");
                            report.WriteLine("Node was not found in the tree");
                        }
                        else
                        {
                            tree.delete(node);
                            Console.WriteLine("The height of the tree is " + tree.Height());
                            report.WriteLine("The height of the tree is " + tree.Height());
                        }
                    }
                    else //add the key if the operation is a 1
                    {
                        Console.WriteLine("Adding node " + node.Data);
                        report.WriteLine("Adding node " + node.Data);
                        tree.add(node);
                        Console.WriteLine("The height of the tree is " + tree.Height());
                        report.WriteLine("The height of the tree is " + tree.Height());
                    }

                    counter++;
                }

                Console.WriteLine();
                Console.WriteLine();

                Console.WriteLine("Tree size " + tree.returnTreeSize());        //normal tree size, just adding the nodes as insert
                Console.WriteLine("Calculated Tree size " + tree.size());       //tracks the nodes size of the subtree
                Console.WriteLine("Tree min value " + tree.minimum().Data);     //the minimum node in the tree
                Console.WriteLine("Tree max value " + tree.maximum().Data);     //the max node in the tree
                Console.WriteLine("tree height " + tree.Height());              // the height of the tree with the original data set
                Console.WriteLine("tree root : " + tree.returnRoot().Data);     //the root of the tree

                report.WriteLine();
                report.WriteLine();

                report.WriteLine("Tree size " + tree.returnTreeSize());        //normal tree size, just adding the nodes as insert
                report.WriteLine("Calculated Tree size " + tree.size());       //tracks the nodes size of the subtree
                report.WriteLine("Tree min value " + tree.minimum().Data);     //the minimum node in the tree
                report.WriteLine("Tree max value " + tree.maximum().Data);     //the max node in the tree
                report.WriteLine("tree height " + tree.Height());              // the height of the tree with the original data set
                report.WriteLine("tree root : " + tree.returnRoot().Data);     //the root of the tree

                file.Close();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                report.WriteLine(e.Message);
            }

            Console.WriteLine("finish");
            Console.ReadLine();
            report.WriteLine("finish");
            //report.ReadLine();
            report.Close();
        }
Example #4
0
 //Private member function that recurses the tree
 //input:    a node x, this case the root of the tree
 //output:   the root of the trees farthest left child, the minimum node of the tree
 private RedBlackNode treeMin(RedBlackNode x)
 {
     if (x.Left == this.nil)
     {
         return x;
     }
     else
     {
         x = treeMin(x.Left);
     }
     return x;
 }
Example #5
0
 //Private member function that recurses the tree
 //input: node x, the root of the tree
 //output: the root of the tree's farhtest right hicld, the max node of the tree.
 private RedBlackNode treeMax(RedBlackNode x)
 {
     if (x.Right == nil)
     {
         return x;
     }
     else
     {
         x = treeMax(x.Right);
     }
     return x;
 }
Example #6
0
 //transplant from CLSR page 323. This function replaces the subtree of one subtree as a child of its parent with another subtree
 //input: two nodes of the tree
 //output:   repalces the subtree rooted at node u with the subtree rooted at node v,
 //          node u's parent becomes node v's parent and u's parent ends up having v as its appropriate child.
 private void Transplant(RedBlackNode u, RedBlackNode 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;
 }
Example #7
0
 //Private member function that corrects the size of the a node after insertions or deletions
 //input: a node x
 //output: x and all of x's parent nodes sizes are updated.
 private int sizeAll(RedBlackNode x)
 {
     if (x.Right == nil && x.Left == nil) //at a leaf node
     {
         x.Size = x.Right.Size + x.Left.Size + 1;
         return x.Size;
     }
     else if (x.Left == nil) // continue down the right subtree
     {
         x.Size = sizeAll(x.Right) + x.Left.Size + 1;
         return x.Size;
     }
     else if (x.Right == nil) // continue down the left subtree
     {
         x.Size = sizeAll(x.Left) + x.Right.Size + 1;
         return x.Size;
     }
     else // this node has two children so begin down the left and then down the right
     {
         x.Size = sizeAll(x.Left) + sizeAll(x.Right) + 1;
         return x.Size;
     }
 }
Example #8
0
 //Private member function that recurses the tree to find a node
 //input: the root of the tree and a node to search for
 //output: true if the node is in the tree, false otherwise
 private RedBlackNode searchRec(RedBlackNode x, int search)
 {
     if(x == nil)// at a sentenil node did not find it return false
     {
         return this.nil;
     }
     else if (x.Data == search) //found it!
     {
         return x;
     }
     else if (search >= x.Data) // what we are looking for is in the right subtree
     {
         return searchRec(x.Right, search);
     }
     else if (search < x.Data) // what we are looking for is in the left subtree
     {
         return searchRec(x.Left, search);
     }
     else //not there again so return nil
     {
         return this.nil;
     }
 }
Example #9
0
 //rotate right
 //input:    node x, at which to pivot rotate left
 //output:   The right rotation pivots around the link from x to y.
 //          It makes y the new root of the subtree, with x as y's right child and y's right child as x's left
 private void RightRotate(RedBlackNode x)
 {
     RedBlackNode y;
     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)
     {
         this.root = y;
     }
     else if (x == x.Parent.Right)
     {
         x.Parent.Right = y;
     }
     else
     {
         x.Parent.Left = y;
     }
     y.Right = x;
     x.Parent = y;
 }
Example #10
0
 //Private member function PreOrderWork is the recursive worker function the traverses the tree and prints it out
 //input: a Redblack node, the root of the calling tree
 //output: A list of the tree in preorder fashion
 private void PreOrderWork(RedBlackNode x)
 {
     if (x == nil)
     {
         return;
     }
     Console.WriteLine("Parent " + x.Parent.Data + " visiting " + x.Data + " Color " + x.Color + " Size " + x.Size);
     PreOrderWork(x.Left);
     PreOrderWork(x.Right);
 }
Example #11
0
 //private member function that recursively finds the node at a given rank i
 //input: a node and the rank to search for
 //output: the node at given rank i
 private RedBlackNode orderSelectRec(RedBlackNode x, int i )
 {
     int r = x.Left.Size + 1;
     if (i == r)
     {
         return x;
     }
     else if (i <= r)
     {
         return orderSelectRec(x.Left, i);
     }
     else
     {
         return orderSelectRec(x.Right, i - r);
     }
 }
Example #12
0
 // Private member function that Recursively finds the height of the tree
 //input: a RedBlack node, the root of the tree and and interger to keep track of the height
 //output: the height of the tree to be returned to the Public Height function
 private int heightRec(RedBlackNode x, int count)
 {
     if (x == this.nil) //if node is sentinel then return
     {
         return -1;
     }
     else
     {
         count = max(heightRec(x.Left, count) , heightRec(x.Right, count)) + 1;
     }
     height = count;
     return count;
 }
Example #13
0
 //RB delete fixup
 //input: node z, where the node z was removed from the tree
 //output: The RedBlack properites of the tree are corrected as result of the deletion
 private void deleteFixup(RedBlackNode x)
 {
     RedBlackNode w = new RedBlackNode();
     while (x != this.root && x.Color == RedBlackNode.BLACK)
     {
         if (x == x.Parent.Left)
         {
             w = x.Parent.Right;
             if (w.Color == RedBlackNode.RED)
             {
                 w.Color = RedBlackNode.BLACK;
                 x.Parent.Color = RedBlackNode.RED;
                 LeftRotate(x.Parent);
                 w = x.Parent.Right;
             }
             if (w.Left.Color == RedBlackNode.BLACK && w.Right.Color == RedBlackNode.BLACK)
             {
                 w.Color = RedBlackNode.RED;
                 x = x.Parent;
             }
             else
             {
                 if (w.Right.Color == RedBlackNode.BLACK)
                 {
                     w.Left.Color = RedBlackNode.BLACK;
                     w.Color = RedBlackNode.RED;
                     x = x.Parent;
                     RightRotate(w);
                     w = x.Parent.Right;
                 }
                 w.Color = x.Parent.Color;
                 x.Parent.Color = RedBlackNode.BLACK;
                 LeftRotate(x.Parent);
                 x = this.root;
             }
         }
         else
         {
             w = x.Parent.Left;
             if (w.Color == RedBlackNode.RED)
             {
                 w.Color = RedBlackNode.BLACK;
                 x.Parent.Color = RedBlackNode.RED;
                 RightRotate(x.Parent);
                 w = x.Parent.Left;
             }
             if (w.Left.Color == RedBlackNode.BLACK && w.Right.Color == RedBlackNode.BLACK)
             {
                 w.Color = RedBlackNode.RED;
                 x = x.Parent;
             }
             else
             {
                 if (w.Left.Color == RedBlackNode.BLACK)
                 {
                     w.Right.Color = RedBlackNode.BLACK;
                     w.Color = RedBlackNode.RED;
                     x = x.Parent;
                     LeftRotate(w);
                     w = x.Parent.Left;
                 }
                 w.Color = x.Parent.Color;
                 x.Parent.Color = RedBlackNode.BLACK;
                 RightRotate(x.Parent);
                 x = this.root;
             }//end inner else
         }//end outter else
     }//end of while loop
 }
Example #14
0
 //public member function that returns the rank of the node sent
 //input: a node x
 //output: the rank of the node x in tree
 public int osRank(RedBlackNode x)
 {
     int r = x.Left.Size + 1;
     RedBlackNode y = x;
     while (y != this.root)
     {
         if (y == y.Parent.Right)
         {
             r = r + y.Parent.Left.Size + 1;
         }
         y = y.Parent;
     }
     return r;
 }
Example #15
0
        //RB insert fixup
        //input:    node z, where the node z was inserted into the tree
        //output:   The RedBlack properites of the tree are corrected as a result from the insertion.
        public void InsertFixup(RedBlackNode z)
        {
            RedBlackNode y;

            while (z.Parent.Color == RedBlackNode.RED)
            {
                if (z.Parent == z.Parent.Parent.Left)
                {
                    y = z.Parent.Parent.Right;
                    if (y != nil && y.Color == RedBlackNode.RED)
                    {
                        z.Parent.Color = RedBlackNode.BLACK;
                        y.Color = RedBlackNode.BLACK;
                        z.Parent.Parent.Color = RedBlackNode.RED;
                        z = z.Parent.Parent;
                    }
                    else
                    {
                        if (z == z.Parent.Right)
                        {
                            z = z.Parent;
                            LeftRotate(z);                              //left rotate at z
                        }

                        z.Parent.Color = RedBlackNode.BLACK;	        // make Parent black
                        z.Parent.Parent.Color = RedBlackNode.RED;		// make grandparent black
                        RightRotate(z.Parent.Parent);					// rotate right
                    }
                }
                else
                {
                    // x's Parent is on the Right subtree
                    // this code is the same as above with "Left" and "Right" swapped
                    y = z.Parent.Parent.Left;
                    if (y != null && y.Color == RedBlackNode.RED)
                    {
                        z.Parent.Color = RedBlackNode.BLACK;
                        y.Color = RedBlackNode.BLACK;
                        z.Parent.Parent.Color = RedBlackNode.RED;
                        z = z.Parent.Parent;
                    }
                    else
                    {
                        if (z == z.Parent.Left)
                        {
                            z = z.Parent;
                            RightRotate(z);
                        }
                        z.Parent.Color = RedBlackNode.BLACK;
                        z.Parent.Parent.Color = RedBlackNode.RED;
                        LeftRotate(z.Parent.Parent);
                    }
                }
            }
            this.root.Color = RedBlackNode.BLACK;

            //recalculate the size of everyone's subtree
            sizeAll(root) ;
        }
Example #16
0
        //Public member function to remove a node from the calling tree
        //input: z, the node to be removed from the calling object, the tree
        //output: Z is removed from the tree and the node's color are fixed.
        public void delete(RedBlackNode z)
        {
            RedBlackNode y = z;
            RedBlackNode x = new RedBlackNode();

            int yOriginalColor = y.Color;

            if (z.Left == nil) //z only has a right child
            {
                x = z.Right;
                this.Transplant(z, z.Right); //swap z with z's right child
            }
            else if (z.Right == nil) //z only has a left child
            {
                x = z.Left;
                this.Transplant(z, z.Left); // swap z with z's left child
            }
            else // z has two children
            {
                y = treeMin(z.Right); // z's replacement
                yOriginalColor = y.Color;
                x = y.Right;

                if (y.Parent == z)
                {
                    x.Parent = y;
                }
                else {
                    this.Transplant(y, y.Right);
                    y.Right = z.Right;
                    y.Right.Parent = y;
                }

                this.Transplant(z, y);
                y.Left = z.Left;
                y.Left.Parent = y;
                y.Color = z.Color;
            }

            if (yOriginalColor == RedBlackNode.BLACK) {
                //Console.WriteLine("I need to call delete fix up");
                this.deleteFixup(x);
            }

            treeSize = treeSize - 1;
            root.Size = sizeAll(root);
        }