Exemple #1
0
        static void Main(string[] args)
        {
            while (true)
            {
                string[] values = { "andrew", "kisya", "kotik",  "evgen", "wkola", "ryry", "kiol",
                                    "sam",    "slava", "baking", "brut",  "truba", "lul",  "poggers","pog","pogu",
                                    "strong", "easy",  "hard",   "imp" };
                var      tree    = new AVLTree.AVLTree();
                Random   rand    = new Random();
                string   entered = "";
                while (true)
                {
                    Console.Clear();
                    tree.Draw();

                    Console.SetCursorPosition(0, 15);
                    Console.WriteLine("Press 0 for restart");
                    Console.WriteLine("Entered values: " + entered);
                    Console.Write("Enter the value: ");
                    try
                    {
                        int value = Convert.ToInt32(Console.ReadLine());
                        if (value == 0)
                        {
                            break;
                        }
                        tree.Add(value);
                        entered += value.ToString() + ", ";
                    }
                    catch { continue; }
                }
            }
        }
Exemple #2
0
        static void Main(string[] args)
        {
            //int[] nums = { 64, 28, 26, 80, 50, 77, 82, 3, 65, 16, 9, 87, 38, 67, 69, 49, 10, 79, 15, 62, 30, 48, 52, 31, 19, 35, 59, 41, 97, 92, 22, 37, 7, 70, 78, 21, 72, 96, 91, 73, 4, 54, 27, 75, 46, 44, 51, 84, 57, 2, 42, 93, 33, 13, 88, 94, 55, 43, 5, 40, 18, 36, 76, 60, 86, 45, 25, 99, 39, 95, 71, 66, 81, 90, 6, 53, 24, 11, 56, 98, 14, 20, 83, 61, 23, 74, 68, 12, 17, 29, 34, 32, 8, 0, 63, 85, 89, 47, 58, 1 };
            int[] nums = { 15, 10, 24, 25, 9, 13, 14, 23, 0, 5, 4, 8, 11, 17, 2, 12, 21, 16, 22, 6, 3, 18, 7, 20, 1, 19 };
            //int[] nums = { 1, 0, 6, 3, 9, 2, 7, 8, 5, 4 };
            //int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12};
            //int[] nums = { 7, 6, 5, 4, 3, 2, 1 };
            //int[] nums = {1,5,7,6,8,9};

            var tree = new AVLTree<int>();

            Console.Write("AVL tree\n\nWild list:\n  ");
            foreach (var i in nums) {
                Console.Write(i + " ");
                tree.Add(i);
            }

            Console.Write("\n\nSorted list:\n  ");
            foreach (var i in tree)
                Console.Write(i + " ");

            Console.Write("\n\nTree count:\n  {0}", tree.Count);

            Console.Write("\n\nVertical tree draw:\n  ");
            Console.Write(tree.ToString());

            Console.Write("\n\nTree root's historical balances:\n  ");
            foreach (int i in tree.HistoricalBalances)
                Console.Write("{0} ", i);

            Console.Write("\n\nHistorical roots:\n  ");
            foreach (var i in tree.HistoricalRoots)
                Console.Write("{0} ", i);

            Console.ReadKey();
        }
Exemple #3
0
 public AVLTreeNode(TNode value, AVLTreeNode <TNode> parent, AVLTree <TNode> tree)
 {
     Value  = value;
     Parent = parent;
     _tree  = tree;
 }
Exemple #4
0
        static void Main(string[] args)
        {
            AVLTree tree = new AVLTree();
            bool    flag = true;

            while (flag)
            {
                Console.Clear();
                Console.WriteLine("Demo: AVLTree of Integer");
                Console.WriteLine("--------------------------------");
                Console.WriteLine("1 - Insert node");
                Console.WriteLine("2 - Delete node");
                Console.WriteLine("3 - Search node");
                Console.WriteLine("4 - Traverse Tree In-Order");
                Console.WriteLine("5 - Display Tree");
                Console.WriteLine("6 - Exit");
                Console.WriteLine("--------------------------------");
                ConsoleKeyInfo cki = Console.ReadKey(true);
                switch (cki.Key)
                {
                case ConsoleKey.D1:
                    Console.WriteLine("Enter node to insert:");
                    string insertInput = Console.ReadLine();
                    if (Int32.TryParse(insertInput, out int insertNode))
                    {
                        tree.Insert(insertNode);
                        Console.WriteLine("Node " + insertNode + " has been inserted.");
                    }
                    else
                    {
                        Console.WriteLine("Invalid input. Enter integer number");
                    }
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;

                case ConsoleKey.D2:
                    Console.WriteLine("Enter node to delete:");
                    string deleteInput = Console.ReadLine();
                    if (Int32.TryParse(deleteInput, out int deleteNode))
                    {
                        if (tree.Search(deleteNode) == null)
                        {
                            Console.WriteLine("No such node in the tree");
                        }
                        else
                        {
                            tree.Delete(deleteNode);
                            Console.WriteLine("Node " + deleteNode + " has been deleted.");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Invalid input. Enter integer number");
                    }
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;

                case ConsoleKey.D3:
                    tree.PrintTree();
                    Console.WriteLine("Enter node to search:");
                    string getInput = Console.ReadLine();
                    if (Int32.TryParse(getInput, out int getNode))
                    {
                        if (tree.Search(getNode) != null)
                        {
                            Console.WriteLine("Node " + getNode + " is present in the tree");
                        }
                        else
                        {
                            Console.WriteLine("No such node in the tree");
                        }
                    }
                    else
                    {
                        Console.WriteLine("Invalid input. Enter integer number");
                    }
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;

                case ConsoleKey.D4:
                    Console.WriteLine("Current tree In-Order traverse:");
                    tree.TraverseInOrder();
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;

                case ConsoleKey.D5:
                    Console.WriteLine("Current tree(from left to right):");
                    tree.PrintTree();
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;

                case ConsoleKey.D6:
                    flag = false;
                    break;

                default:
                    Console.WriteLine("Invalid menu item, enter numbers 1-4");
                    Console.WriteLine("\nPress any key...");
                    Console.ReadLine();
                    break;
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Deletes the given key from the tree, if present.
        /// </summary>
        /// <param name="key"></param>
        /// <returns>True if the depth of the tree decreased.</returns>
        public bool Delete(int key)
        {
            if (this.isHead)
            {
                // empty tree
                if (this.rightChild == null)
                {
                    return(false);
                }
                // delete recursively from the tree
                else
                {
                    return(this.rightChild.Delete(key));
                }
            }

            // recursively try to find and delete the key
            switch (key.CompareTo(this.key))
            {
            // look in the right subtree
            case 1:
            {
                // key is not in the tree, do nothing
                if (rightChild == null)
                {
                    break;
                }

                // delete the key from the right subtree
                bool depthDecreased = rightChild.Delete(key);

                // check balance
                if (depthDecreased)
                {
                    switch (this.balance)
                    {
                    // the node is being balanced, but the depth decreases -> send the information to the upper levels
                    case 1:
                    {
                        balance--;
                        return(true);
                    }

                    // node is being unbalanced to the left, the depth does NOT decrease
                    case 0:
                    {
                        balance--;
                        return(false);
                    }

                    // node is already unbalanced to the left, now double unbalanced -> need to rotate
                    case -1:
                    {
                        balance--;
                        switch (leftChild.balance)
                        {
                        // rotate right, depth decreases
                        case -1:
                        {
                            RotateRight(this);
                            return(true);
                        }

                        // rotate right, depth does NOT decrease
                        case 0:
                        {
                            RotateRight(this);
                            return(false);
                        }

                        // double rotate, depth decreases
                        case 1:
                        {
                            RotateLeft(this.leftChild);
                            RotateRight(this);
                            return(true);
                        }

                        default:
                            return(false);
                        }
                    }

                    default:
                        break;
                    }
                }
                break;
            }

            // look in the right subtree
            case -1:
            {
                // key is not in the tree, do nothing
                if (leftChild == null)
                {
                    break;
                }

                // delete the key from the left subtree
                bool depthDecreased = leftChild.Delete(key);

                // check balance
                if (depthDecreased)
                {
                    switch (this.balance)
                    {
                    // the node is being balanced, but the depth decreases -> send the information to the upper levels
                    case -1:
                    {
                        balance++;
                        return(true);
                    }

                    // node is being unbalanced to the right, the depth does NOT decrease
                    case 0:
                    {
                        balance++;
                        return(false);
                    }

                    // node is already unbalanced to the right, now double unbalanced -> need to rotate
                    case 1:
                    {
                        balance++;
                        switch (rightChild.balance)
                        {
                        // rotate left, depth decreases
                        case 1:
                        {
                            RotateLeft(this);
                            return(true);
                        }

                        // rotate left, depth does NOT decrease
                        case 0:
                        {
                            RotateLeft(this);
                            return(false);
                        }

                        // double rotate, depth decreases
                        case -1:
                        {
                            RotateRight(this.rightChild);
                            RotateLeft(this);
                            return(true);
                        }

                        default:
                            return(false);
                        }
                    }

                    default:
                        break;
                    }
                }
                break;
            }

            // we have found the key, now we will delete it
            case 0:
            {
                // node is leaf, simply delete
                if ((this.rightChild == null) && (this.leftChild == null))
                {
                    if (this.key < parent.key)
                    {
                        parent.leftChild = null;
                    }
                    else
                    {
                        parent.rightChild = null;
                    }
                    return(true);
                }
                // node has only a left child, just reconnect it
                else if (this.rightChild == null)
                {
                    if (this.key < parent.key)
                    {
                        parent.leftChild      = this.leftChild;
                        this.leftChild.parent = this.parent;
                    }
                    else
                    {
                        parent.rightChild     = this.leftChild;
                        this.leftChild.parent = this.parent;
                    }
                    return(true);
                }
                // node has only a right child, just reconnect it
                else if (this.leftChild == null)
                {
                    if (this.key < parent.key)
                    {
                        parent.leftChild       = this.rightChild;
                        this.rightChild.parent = this.parent;
                    }
                    else
                    {
                        parent.rightChild      = this.rightChild;
                        this.rightChild.parent = this.parent;
                    }
                    return(true);
                }
                // node has both children, replace it with a node from the subtree
                else
                {
                    int replacementKey;
                    // choose the replacement in the deeper subtree (avoid disbalancing)
                    if (this.balance == -1)
                    {
                        replacementKey = leftChild.findMaxKey();
                    }
                    else
                    {
                        replacementKey = rightChild.findMinKey();
                    }

                    // delete the replacement key (it has surely atmost one child)
                    bool depthDecreased = this.Delete(replacementKey);

                    // replace the key in this node by the key of the deleted replacement
                    this.key = replacementKey;

                    // deleting in the subtree might change depth, propagate
                    return(depthDecreased);
                }
            }

            default:
                break;
            }
            return(false);
        }
Exemple #6
0
        /// <summary>
        /// Inserts the given key into the tree.
        /// </summary>
        /// <param name="key"></param>
        /// <returns>True if the depth of the tree increased.</returns>
        public bool Insert(int key)
        {
            // empty node, simply fill with key
            if (this.containsKey == false)
            {
                this.key         = key;
                this.containsKey = true;
                // depth increased
                return(true);
            }
            // non-empty node, insert to the correct subtree
            else
            {
                switch (key.CompareTo(this.key))
                {
                // insert to the right subtree
                case 1:
                {
                    // create right child if nonexistent
                    if (rightChild == null)
                    {
                        rightChild = new AVLTree(this);
                    }

                    // insert the key to the left subtree
                    bool depthIncreased = rightChild.Insert(key);

                    // check balance
                    if (depthIncreased)
                    {
                        // head does not need to be balanced
                        if (this.isHead == true)
                        {
                            break;
                        }

                        switch (this.balance)
                        {
                        // right subtree was deeper, now increased by another level -> rotation necessary
                        case 1:
                        {
                            this.balance++;

                            // single left rotation
                            if (this.rightChild.balance == 1)
                            {
                                RotateLeft(this);
                            }

                            // double rotation
                            else if (this.rightChild.balance == -1)
                            {
                                RotateRight(this.rightChild);
                                RotateLeft(this);
                            }
                            // balance of the right child cannot be 0, the depth would not increase in such case

                            // tree has been balanced and the depth change does not propagate any further
                            return(false);
                        }

                        case 0:
                        {
                            // right child was balanced, now it will be unbalanced by one (still OK) - propagate the information about depth increase to the upper levels
                            this.balance++;
                            return(true);
                        }

                        case -1:
                        {
                            // right child was unbalanced to the left, now it will be balanced and the depth will stay the same
                            this.balance++;
                            return(false);
                        }

                        default:
                            break;
                        }
                    }
                    break;
                }

                // insert to the left subtree (mirror situation)
                case -1:
                {
                    // create right child if nonexistent
                    if (leftChild == null)
                    {
                        leftChild = new AVLTree(this);
                    }

                    // insert the key to the left subtree
                    if (leftChild.Insert(key))
                    {
                        // head does not need to be balanced
                        if (this.isHead == true)
                        {
                            break;
                        }
                        switch (this.balance)
                        {
                        // left subtree was deeper, now increased by another level -> rotation necessary
                        case -1:
                        {
                            this.balance--;

                            // single right rotation
                            if (this.leftChild.balance == -1)
                            {
                                RotateRight(this);
                            }

                            // double rotation
                            else if (this.leftChild.balance == 1)
                            {
                                RotateLeft(this.leftChild);
                                RotateRight(this);
                            }

                            // balance of the left child cannot be 0, the depth would not increase in such case

                            // tree has been balanced and the depth change does not propagate any further
                            return(false);
                        }

                        case 0:
                        {
                            // left child was balanced, now it will be unbalanced by one (still OK) - propagate the information about depth increase to the upper levels
                            this.balance--;
                            return(true);
                        }

                        case 1:
                        {
                            // left child was unbalanced to the right, now it will be balanced and the depth will stay the same
                            this.balance--;
                            return(false);
                        }

                        default:
                            break;
                        }
                    }
                    break;
                }

                // key is already in the tree, do nothing
                case 0:
                    break;

                default:
                    break;
                }
            }
            return(false);
        }