Exemplo n.º 1
0
        //Quickly fix the height values of the node, does not care about updating the values of parents
        //This is only called on nodes that I know need updating and dont effect the rest of the tree (ei the moved node in LR or RL balance issue)
        private void quickFixHeight(ADSNode n)
        {
            int l = (n.left == null) ? 0 : n.left.height + 1;
            int r = (n.right == null) ? 0 : n.right.height + 1;

            n.height = Math.Max(l, r);
        }
Exemplo n.º 2
0
        private void Balance(ref ADSNode imbalancedNode)
        {
            var imbalanceType = ImbalanceType(imbalancedNode);

            if (imbalanceType == "LR")
            {
                // left sub-rotation
                imbalancedNode.Left = LeftRotation(imbalancedNode.Left);

                // right rotation
                imbalancedNode = RightRotation(imbalancedNode);
            }

            if (imbalanceType == "LL")
            {
                imbalancedNode = RightRotation(imbalancedNode);
            }

            if (imbalanceType == "RR")
            {
                imbalancedNode = LeftRotation(imbalancedNode);
            }

            if (imbalanceType == "RL")
            {
                // right sub-rotation
                imbalancedNode.Right = RightRotation(imbalancedNode.Right);

                // left rotation
                imbalancedNode = LeftRotation(imbalancedNode);
            }
        }
Exemplo n.º 3
0
        // Return the node where value is located
        public ADSNode Find(T value)
        {
            ADSNode current = Root;

            while (true)
            {
                if (current == null)
                {
                    return(null);
                }

                if (value.CompareTo(current.Key) == 0)
                {
                    return(current);
                }

                if (value.CompareTo(current.Key) < 0)
                {
                    current = current.Left;
                }
                else
                {
                    current = current.Right;
                }
            }
        }
Exemplo n.º 4
0
        // Inserts a node into the tree and maintains it's balance
        public void insert(int value)
        {
            //Insert to root if null
            if (root == null)
            {
                root = new ADSNode()
                {
                    key = value
                }
            }
            ;
            //Try to recursively insert node
            else
            {
                ADSNode n = addNode(root, value);

                //This is not neaded for root, so just discard this data
                if (n.height < 0)
                {
                    n.height *= -1;
                }

                root = n;
            }

            //If you overwrite a node in your insertion, put that back in (IDK if this is most efficient, but its what im doing)
            while (overwritenNode != null)
            {
                insert(overwritenNode.key);
            }
        }
Exemplo n.º 5
0
        //fix balance on a specific node, returns the new head node reference
        private ADSNode fixBalance(ADSNode node)
        {
            //Gets the type of ballance issue;
            string type = heavy(node, false);

            if (type == "RR")
            {
                return(leftRotate(node));
            }

            else if (type == "LL")
            {
                return(rightRotate(node));
            }

            else if (type == "LR")
            {
                node.left = leftRotate(node.left);
                return(rightRotate(node));
            }

            else //RL
            {
                node.right = rightRotate(node.right);
                return(leftRotate(node));
            }
        }
Exemplo n.º 6
0
        private void PrintRecursive(ADSNode node, TraverseOrder order)
        {
            if (node == null)
            {
                return;
            }

            // used to output a tree to be loaded again without rebalancing
            if (order == TraverseOrder.PreOrder)
            {
                Console.Write(node.Key + " ");
            }

            PrintRecursive(node.Left, order);

            // used to print a tree for readability
            if (order == TraverseOrder.InOrder)
            {
                Console.Write(node.Key + " ");
            }

            PrintRecursive(node.Right, order);

            // used to print a tree to be deleted efficeintly
            if (order == TraverseOrder.PostOrder)
            {
                Console.Write(node.Key + " ");
            }
        }
Exemplo n.º 7
0
        // Inserts a node into the tree and maintains its balance
        public void Insert(T value)
        {
            var newNode = new ADSNode
            {
                Key         = value,
                Cardinality = 1
            };

            InsertNode(ref Root, newNode);
        }
Exemplo n.º 8
0
        private ADSNode LeftRotation(ADSNode imbalancedNode)
        {
            var tempNode = imbalancedNode.Right;

            imbalancedNode.Right = tempNode.Left;

            tempNode.Left = imbalancedNode;

            return(tempNode);
        }
Exemplo n.º 9
0
        private ADSNode leftRotation(ADSNode node)
        {
            ADSNode newRoot = node.right;
            ADSNode temp    = (newRoot.left == null) ? null : newRoot.left;

            newRoot.left = node;

            node.right = temp;

            return(newRoot);
        }
Exemplo n.º 10
0
        public static void PostOrderTraversal(ADSNode root)
        {
            if (root == null)
            {
                return;
            }

            PostOrderTraversal(root.left);  // process the left
            PostOrderTraversal(root.right); // process the right
            Console.WriteLine(root.key);    // process the root
        }
Exemplo n.º 11
0
        private ADSNode rightRotation(ADSNode node)
        {
            //should return newRoot
            ADSNode newRoot = node.left;
            ADSNode temp    = (newRoot.right == null) ? null : newRoot.right;

            newRoot.right = node;

            node.left = temp;

            return(newRoot);
        }
Exemplo n.º 12
0
        private ADSNode rightLeftRotation(ADSNode node)
        {
            ADSNode temp = node.right;

            ADSNode newRoot = node.right.left;

            temp.left     = null;
            node.right    = newRoot;
            newRoot.right = temp;

            return(node);
        }
Exemplo n.º 13
0
 private string ImbalanceType(ADSNode node)
 {
     if (node.LeftHeight > node.RightHeight)
     {
         node = node.Left;
         return(node.LeftHeight > node.RightHeight ? "LL" : "LR");
     }
     else
     {
         node = node.Right;
         return(node.LeftHeight > node.RightHeight ? "RL" : "RR");
     }
 }
Exemplo n.º 14
0
        //Same as left rotation, but opposite
        private ADSNode rightRotate(ADSNode node)
        {
            ADSNode ret = node.left;

            overwritenNode  = node.left.right;
            node.left.right = node;
            node.left       = null;

            quickFixHeight(ret.right);
            quickFixHeight(ret);

            return(ret);
        }
Exemplo n.º 15
0
        public void printTree(ADSNode node, TraverseOrder order)
        {
            if (node == null)
            {
                return;
            }

            printTree(node.left, order);
            if (order == TraverseOrder.InOrder)
            {
                Console.Write(node.key);
            }
            printTree(node.right, order);
        }
Exemplo n.º 16
0
        private void breathPrint(ADSNode n)
        {
            int size = 64;
            List <List <ADSNode> > children = new List <List <ADSNode> >();

            children.Add(new List <ADSNode> {
                root
            });
            while (true)
            {
                children.Add(new List <ADSNode>());
                bool cont = false;
                foreach (ADSNode child in children[0])
                {
                    if (child == null)
                    {
                        Console.Write("- ".PadLeft(size / 2).PadRight(size));
                        children[1].Add(null);
                        children[1].Add(null);
                        continue;
                    }
                    cont = true;
                    Console.Write((child.key + "").PadLeft(size / 2).PadRight(size));
                    if (child.left != null)
                    {
                        children[1].Add(child.left);
                    }
                    else
                    {
                        children[1].Add(null);
                    }
                    if (child.right != null)
                    {
                        children[1].Add(child.right);
                    }
                    else
                    {
                        children[1].Add(null);
                    }
                }
                Console.WriteLine("\n");
                children.RemoveAt(0);
                size /= 2;
                if (!cont)
                {
                    break;
                }
            }
        }
Exemplo n.º 17
0
 // Inserts a node into the tree and maintains its balance
 public void insert(int value)
 {
     if (root == null)
     {
         root = new ADSNode()
         {
             key = value
         }
     }
     ;
     else
     {
         root = insert(value, root);
     }
 }
Exemplo n.º 18
0
        //Rotate tree at node to the left
        private ADSNode leftRotate(ADSNode node)
        {
            ADSNode ret = node.right;

            //Move parent node to be under child
            overwritenNode  = node.right.left;
            node.right.left = node;
            node.right      = null;

            //Ret is new head node, ret.left is old head node
            //Update their heights
            quickFixHeight(ret.left);
            quickFixHeight(ret);

            return(ret);
        }
Exemplo n.º 19
0
        public ADSNode updateHeight(ADSNode node)
        {
            int left  = (node.left == null) ? 0 : node.left.height + 1;
            int right = (node.right == null) ? 0 : node.right.height + 1;

            int height = Math.Max(left, right);

            node.height = height;

            int difference = Math.Abs(right - left);

            if (difference >= 2)
            {
                node = balance(node);
            }

            return(node);
        }
Exemplo n.º 20
0
        //Get type from pos
        private string heavy(ADSNode n, bool done = true)
        {
            //Gets the heights at a pos
            int l = (n.left == null) ? 0 : n.left.height + 1;
            int r = (n.right == null) ? 0 : n.right.height + 1;

            //Gets which is greater
            string val = (l > r) ? "L" : "R";

            //If your done, return
            if (done)
            {
                return(val);
            }

            //If not, add the char and continue
            return(val + ((val == "L") ? heavy(n.left) : heavy(n.right)));
        }
Exemplo n.º 21
0
        // Inserts a node into the tree and maintains it's balance
        public void insert(ADSNode parent, int value)
        {
            ADSNode n = new ADSNode();

            if (root == null)
            {
                root = new ADSNode();
            }
            else
            {
            }
            if (value < parent.key)
            {
                if (parent.left == null)
                {
                    //create new node
                    n.key       = value;
                    parent.left = n;
                }
                else
                {
                    insert(parent.right, value);

                    parent.height = Math.Max(parent.left == null ? 0 : parent.left.height,
                                             parent.right == null ? 0 : parent.right.height) + 1;
                }
            }
            else if (value > parent.key)
            {
                if (parent.right == null)
                {
                    //create new node
                    n.key        = value;
                    parent.right = n;
                }
                else
                {
                    insert(parent.right, value);

                    parent.height = Math.Max(parent.right == null ? 0 : parent.right.height,
                                             parent.left == null ? 0 : parent.left.height) + 1;
                }
            }
        }
Exemplo n.º 22
0
        private ADSNode InsertNode(ref ADSNode head, ADSNode data)
        {
            if (head == null)
            {
                // do the insert
                head = data;
                return(head);
            }

            int keyComparison = head.Key.CompareTo(data.Key);

            if (keyComparison == 0)
            {
                head.Cardinality++;
                return(head);
            }
            else if (keyComparison < 0)
            {
                head.Right = InsertNode(ref head.Right, data);
            }
            else
            {
                head.Left = InsertNode(ref head.Left, data);
            }

            // attempt to rebalance when bubbling up
            if (Math.Abs(head.LeftHeight - head.RightHeight) > 1)
            {
                Balance(ref head);

                // recalculate heights
                head.Left?.RecalculateHeight();
                head.Right?.RecalculateHeight();
            }

            head.RecalculateHeight();

            return(head);
        }
Exemplo n.º 23
0
        public void insert(ADSNode parent, int value)
        {
            if (value > parent.key)
            {
                if (parent.right == null)
                {
                    // Create a new node connected to parent.right
                    ADSNode n = new ADSNode();
                    n.key        = value;
                    parent.right = n;
                }
                else
                {
                    insert(parent.right, value);

                    parent.height = Math.Max(parent.left == null ? 0 : parent.left.height,
                                             parent.right == null ? 0 : parent.right.height) + 1;
                }
            }
            else if (value < parent.key)
            {
                if (parent.left == null)
                {
                    // create a new node connected to parent.left
                    ADSNode n = new ADSNode();
                    n.key       = value;
                    parent.left = n;
                }
                else
                {
                    insert(parent.left, value);

                    parent.height = Math.Max(parent.left == null ? 0 : parent.left.height,
                                             parent.right == null ? 0 : parent.right.height) + 1;
                }
            }
        }
Exemplo n.º 24
0
        // Inserts a node into the tree and maintains it's balance
        public void insert(int value)
        {
            ADSNode n = new ADSNode();

            n.left        = null;
            n.right       = null;
            n.key         = value;
            n.cardinality = 0;
            n.height      = 0;

            ADSNode node = root;

            while (true)
            {
                if (value > node.key)
                {
                    if (node.right == null)
                    {
                        node.right = n;
                        break;
                    }
                    else
                    {
                        node = node.right;
                    }
                }
                else if (value == root.key)
                {
                    node.cardinality++;
                }
                else if (value < root.key)
                {
                    root.left = n;
                }
            }
        }
Exemplo n.º 25
0
        //Takes a node and updates its height returns true if the height changed
        private ADSNode updateHeight(ADSNode n)
        {
            //Get the heights of the side nodes
            int l = (n.left == null) ? 0 : n.left.height + 1;
            int r = (n.right == null) ? 0 : n.right.height + 1;

            //Heavy on one side ? fix the balance
            if (Math.Abs(l - r) == 2)
            {
                return(fixBalance(n));
            }

            //Save adjusted height
            int adjustedHeight = Math.Max(l, r);

            //If it is different, change it and indicate it by making it negative
            if (adjustedHeight != n.height)
            {
                n.height = -adjustedHeight;
            }

            //return node with changes
            return(n);
        }
Exemplo n.º 26
0
 public ADSTree()
 {
     root = null;
 }
Exemplo n.º 27
0
 public ADSTree()
 {
     Root = null;
 }
Exemplo n.º 28
0
        //adds a node to the tree and updates the heights as you go
        private ADSNode addNode(ADSNode n, int val)
        {
            //Increment cardinality and return, they are the same so nothing changes
            if (n.key == val)
            {
                n.cardinality++;
                return(n);
            }

            ADSNode side = (val > n.key) ? n.right : n.left;

            //You found your side, then inert it and you good
            if (side == null)
            {
                //If you are inserting a whole node and not just a value, then do that
                if (overwritenNode != null)
                {
                    side           = overwritenNode;
                    overwritenNode = null;
                }
                else
                {
                    side = new ADSNode()
                    {
                        key = val
                    }
                };

                //Adds node to propper size
                if (n.key > val)
                {
                    n.left = side;
                }
                else
                {
                    n.right = side;
                }

                return(updateHeight(n));
            }

            //It wasnt ment to be inserted here, but it was inserted later.
            //This returns the new child reference just incase the insert shifted the tree
            ADSNode child = addNode(side, val);

            //Reasign references, they could have chnaged
            if (n.key > val)
            {
                n.left = child;
            }
            else
            {
                n.right = child;
            }

            //The sign of the int is used to determine if this node should re-adjust its height values
            if (child.height < 0)
            {
                child.height *= -1;

                //Update the node to see if the heights need to be adjusted and return it
                return(updateHeight(n));
            }

            return(n);
        }