예제 #1
0
        // Метод добавлет новый узел

        public void Insert(T value)
        {
            // Вариант 1:  Дерево пустое - создание корня дерева
            if (Head == null)
            {
                Head = new AvlNode <T>(value, null, this);
            }

            // Вариант 2: Дерево не пустое - найти место для добавление нового узла.

            else
            {
                AddTo(Head, value);
            }

            Count++;
        }
예제 #2
0
        }         //insert

        private void InsertBalance(AvlNode <@int, @string> node, int balance)
        {
            while (node != null)
            {
                balance = (node.Balance += balance);

                if (balance == 0)
                {
                    return;
                }
                else if (balance == 2)
                {
                    if (node.Left.Balance == 1)
                    {
                        RotateRight(node);
                    }
                    else
                    {
                        RotateLeftRight(node);
                    }
                    return;
                }
                else if (balance == -2)
                {
                    if (node.Right.Balance == -1)
                    {
                        RotateLeft(node);
                    }
                    else
                    {
                        RotateRightLeft(node);
                    }
                    return;
                }

                AvlNode <@int, @string> parent = node.Parent;

                if (parent != null)
                {
                    balance = parent.Left == node ? 1 : -1;
                }
                node = parent;
            }     //while
        }         //insertBalance
예제 #3
0
        }         //deleteBalance

        private static void Replace(AvlNode <@int, @string> target, AvlNode <@int, @string> source)
        {
            AvlNode <@int, @string> left  = source.Left;
            AvlNode <@int, @string> right = source.Right;

            target.Balance = source.Balance;
            target.Key     = source.Key;
            target.Value   = source.Value;
            target.Left    = left;
            target.Right   = right;

            if (left != null)
            {
                left.Parent = target;
            }
            if (right != null)
            {
                right.Parent = target;
            }
        }
예제 #4
0
        public AvlNode <int, string> Search(int key)
        {
            AvlNode <int, string> node = _root;

            while (node != null)
            {
                if (_comparer.Compare(key, node.Key) == 0)
                {
                    return(node);
                }
                if (_comparer.Compare(key, node.Key) < 0)
                {
                    node = node.Left;
                }
                else if (_comparer.Compare(key, node.Key) > 0)
                {
                    node = node.Right;
                }
            }
            return(null);
        }         //search
예제 #5
0
        private void ReplaceRoot(AvlNode <TNode> newRoot)
        {
            if (this.Parent != null)
            {
                if (this.Parent.Left == this)
                {
                    this.Parent.Left = newRoot;
                }
                else if (this.Parent.Right == this)
                {
                    this.Parent.Right = newRoot;
                }
            }
            else
            {
                _tree.Head = newRoot;
            }

            newRoot.Parent = this.Parent;
            this.Parent    = newRoot;
            newRoot.Balance();
        }
예제 #6
0
        private void LeftRotation()
        {
            // До
            //     12(this)
            //      \ 
            //       15
            //        \ 
            //         25
            //
            // После
            //       15
            //      / \ 
            //     12  25

            // Сделать правого потомка новым корнем дерева.
            AvlNode <TNode> newRoot = Right;

            ReplaceRoot(newRoot);

            // Поставить на место правого потомка - левого потомка нового корня.
            Right = newRoot.Left;
            // Сделать текущий узел - левым потомком нового корня.
            newRoot.Left = this;
        }
예제 #7
0
        public bool Search(@int key, out @string value)
        {
            AvlNode <@int, @string> node = _root;

            while (node != null)
            {
                if (_comparer.Compare(key, node.Key) < 0)
                {
                    node = node.Left;
                }
                else if (_comparer.Compare(key, node.Key) > 0)
                {
                    node = node.Right;
                }
                else
                {
                    value = node.Value;
                    return(true);
                }
            }

            value = default(@string);
            return(false);
        }         //search
예제 #8
0
        // Алгоритм рекурсивного добавления нового узла в дерево.

        private void AddTo(AvlNode <T> node, T value)
        {
            // Вариант 1: Добавление нового узла в дерево. Значение добавлемого узла меньше чем значение текущего узла.

            if (value.CompareTo(node.Value) < 0)
            {
                //Создание левого узла, если его нет.

                if (node.Left == null)
                {
                    node.Left = new AvlNode <T>(value, node, this);
                }

                else
                {
                    // Переходим к следующему левому узлу
                    AddTo(node.Left, value);
                }
            }
            // Вариант 2: Добавлемое значение больше или равно текущему значению.

            else
            {
                //Создание правого узла, если его нет.
                if (node.Right == null)
                {
                    node.Right = new AvlNode <T>(value, node, this);
                }
                else
                {
                    // Переход к следующему правому узлу.
                    AddTo(node.Right, value);
                }
            }
            node.Balance();
        }
예제 #9
0
 public void Reset()
 {
     _right  = _root;
     _action = _root == null ? Action.End : Action.Right;
 }
예제 #10
0
 public AvlNodeEnumerator(AvlNode <@int, @string> root)
 {
     _right  = _root = root;
     _action = _root == null ? Action.End : Action.Right;
 }
예제 #11
0
        static void Main(string[] args)
        {
            string agencia, conta, diretorio;
            int    opcao;
            AvlNode <int, string> node   = new AvlNode <int, string>();
            ArvoreAgencias        arvore = new ArvoreAgencias(@"C:\Users\nara-\Documents\projeto_AED2\arquivos\agencias");
            AvlTree <int, string> raiz   = arvore.Inicializacao();


            Console.WriteLine("Bem-Vindo ao sistema de Agências!\n");

            while (true)
            {
                Console.WriteLine("O que deseja fazer?");
                Console.WriteLine("1-Saber a quem pertence uma conta específica;");
                Console.WriteLine("2-Saber quantas contas estão vinculadas a uma agência;");
                Console.WriteLine("3-Saber quantas agências estão registradas no sistema;");
                Console.WriteLine("4-Saber qual o saldo de uma conta específica;");
                Console.WriteLine("5-Sair;");

                opcao = int.Parse(Console.ReadLine());

                switch (opcao)
                {
                case 1:
                    Console.WriteLine("Insira a agência que deseja buscar:");
                    agencia = Console.ReadLine().Trim();
                    node    = raiz.Search(int.Parse(agencia));

                    if (node == null)
                    {
                        Console.WriteLine("Ops! Não encontramos essa agencia");
                    }
                    else
                    {
                        Console.WriteLine("Insira a conta vinculada a esta agência que deseja buscar:");
                        conta = Console.ReadLine().Trim();

                        diretorio = node.Value;
                        BuscaArquivo(conta, diretorio);

                        if (listaCorrespondencia.Count > 0)
                        {
                            foreach (var item in listaCorrespondencia)
                            {
                                Console.WriteLine("O cliente vinculado a essa conta é " + retornaCliente(item) + ".\n");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Não há clientes que possuem o número de conta procurado.");
                        }
                    }
                    break;

                case 2:
                    Console.WriteLine("Insira a agência:");
                    agencia = Console.ReadLine().Trim();
                    node    = raiz.Search(int.Parse(agencia));

                    if (node == null)
                    {
                        Console.WriteLine("Ops! não encontramos essa agencia!");
                    }
                    else
                    {
                        diretorio = node.Value;
                        int count = File.ReadAllLines(diretorio).Count();
                        Console.WriteLine("Há " + Convert.ToString(count) + " contas vinculadas a essa agência.\n");
                    }
                    break;

                case 3:
                    Console.WriteLine("Há " + arvore.Count() + " agências vinculadas ao sistema.\n");
                    break;

                case 4:
                    Console.WriteLine("Insira a agência que deseja buscar:");
                    agencia = Console.ReadLine().Trim();
                    node    = raiz.Search(int.Parse(agencia));

                    if (node == null)
                    {
                        Console.WriteLine("Ops! Não encontramos essa agencia");
                    }
                    else
                    {
                        Console.WriteLine("Insira a conta vinculada a esta agência que deseja buscar:");
                        conta = Console.ReadLine().Trim();

                        diretorio = node.Value;
                        BuscaArquivo(conta, diretorio);

                        if (listaCorrespondencia.Count > 0)
                        {
                            foreach (var item in listaCorrespondencia)
                            {
                                Console.WriteLine("O cliente " + retornaCliente(item) + " possui " + retornaSaldoCliente(item) + " em sua conta.\n");
                            }
                        }
                        else
                        {
                            Console.WriteLine("Não há clientes que possuem o número de conta procurado.");
                        }
                    }
                    break;

                case 5:
                    return;
                }
            }



            Console.ReadKey();
        }
예제 #12
0
        AvlNode <TNode> _right; // правый потомок


        #region Конструктор

        public AvlNode(TNode value, AvlNode <TNode> parent, AvlTree <TNode> tree)
        {
            Value  = value;
            Parent = parent;
            _tree  = tree;
        }
예제 #13
0
        }         //rotateRightLeft

        public bool Delete(@int key)
        {
            AvlNode <@int, @string> node = _root;

            while (node != null)
            {
                if (_comparer.Compare(key, node.Key) < 0)
                {
                    node = node.Left;
                }
                else if (_comparer.Compare(key, node.Key) > 0)
                {
                    node = node.Right;
                }
                else
                {
                    AvlNode <@int, @string> left  = node.Left;
                    AvlNode <@int, @string> right = node.Right;

                    if (left == null)
                    {
                        if (right == null)
                        {
                            if (node == _root)
                            {
                                _root = null;
                            }
                            else
                            {
                                AvlNode <@int, @string> parent = node.Parent;

                                if (parent.Left == node)
                                {
                                    parent.Left = null;
                                    DeleteBalance(parent, -1);
                                }
                                else
                                {
                                    parent.Right = null;
                                    DeleteBalance(parent, 1);
                                }
                            }
                        }
                        else
                        {
                            Replace(node, right);
                            DeleteBalance(node, 0);
                        }
                    }
                    else if (right == null)
                    {
                        Replace(node, left);
                        DeleteBalance(node, 0);
                    }
                    else
                    {
                        AvlNode <@int, @string> successor = right;

                        if (successor.Left == null)
                        {
                            AvlNode <@int, @string> parent = node.Parent;

                            successor.Parent  = parent;
                            successor.Left    = left;
                            successor.Balance = node.Balance;
                            left.Parent       = successor;

                            if (node == _root)
                            {
                                _root = successor;
                            }
                            else
                            {
                                if (parent.Left == node)
                                {
                                    parent.Left = successor;
                                }
                                else
                                {
                                    parent.Right = successor;
                                }
                            }

                            DeleteBalance(successor, 1);
                        }
                        else
                        {
                            while (successor.Left != null)
                            {
                                successor = successor.Left;
                            }

                            AvlNode <@int, @string> parent          = node.Parent;
                            AvlNode <@int, @string> successorParent = successor.Parent;
                            AvlNode <@int, @string> successorRight  = successor.Right;

                            if (successorParent.Left == successor)
                            {
                                successorParent.Left = successorRight;
                            }
                            else
                            {
                                successorParent.Right = successorRight;
                            }

                            if (successorRight != null)
                            {
                                successorRight.Parent = successorParent;
                            }

                            successor.Parent  = parent;
                            successor.Left    = left;
                            successor.Balance = node.Balance;
                            successor.Right   = right;
                            right.Parent      = successor;
                            left.Parent       = successor;

                            if (node == _root)
                            {
                                _root = successor;
                            }
                            else
                            {
                                if (parent.Left == node)
                                {
                                    parent.Left = successor;
                                }
                                else
                                {
                                    parent.Right = successor;
                                }
                            }

                            DeleteBalance(successorParent, -1);
                        }
                    }
                    return(true);
                } //else
            }     //while
            return(false);
        }         //delete
예제 #14
0
        public bool Remove(T value)
        {
            AvlNode <T> current;

            current = Find(value); // находим узел с удаляемым значением

            if (current == null)   // узел не найден
            {
                return(false);
            }

            AvlNode <T> toBalance  = current.Parent; // баланс дерева относительно узла родителя
            var         toBalanceP = toBalance.Parent;

            Count--;                                       // уменьшение колиества узлов

            // Вариант 1: Если удаляемый узел не имеет правого потомка

            if (current.Right == null)      // если нет правого потомка
            {
                if (current.Parent == null) // удаляемый узел является корнем
                {
                    Head = current.Left;    // на место корня перемещаем левого потомка

                    if (Head != null)
                    {
                        Head.Parent = null; // убераем ссылку на родителя
                    }
                }
                else // удаляемый узел не является корнем
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        // Если значение родительского узла больше значения удаляемого,
                        // сделать левого потомка удаляемого узла, левым потомком родителя.

                        current.Parent.Left = current.Left;
                    }
                    else if (result < 0)
                    {
                        // Если значение родительского узла меньше чем удаляемого,
                        // сделать левого потомка удаляемого узла - правым потомком родительского узла.

                        current.Parent.Right = current.Left;
                    }
                }
            }

            // Вариант 2: Если правый потомок удаляемого узла не имеет левого потомка, тогда правый потомок удаляемого узла
            // становится потомком родительского узла.

            else if (current.Right.Left == null) // если у правого потомка нет левого потомка
            {
                current.Right.Left = current.Left;

                if (current.Parent == null) // текущий элемент является корнем
                {
                    Head = current.Right;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);
                    if (result > 0)
                    {
                        // Если значение узла родителя больше чем значение удаляемого узла,
                        // сделать правого потомка удаляемого узла, левым потомком его родителя.

                        current.Parent.Left = current.Right;
                    }

                    else if (result < 0)
                    {
                        // Если значение родительского узла меньше значения удаляемого,
                        // сделать правого потомка удаляемого узла - правым потомком родителя.

                        current.Parent.Right = current.Right;
                    }
                }
            }

            // Вариант 3: Если правый потомок удаляемого узла имеет левого потомка,
            // заместить удаляемый узел, крайним левым потомком правого потомка.
            else
            {
                // Нахожление крайнего левого узла для правого потомка удаляемого узла.

                AvlNode <T> leftmost = current.Right.Left;

                while (leftmost.Left != null)
                {
                    leftmost = leftmost.Left;
                }

                // Родительское правое поддерево становится родительским левым поддеревом.

                leftmost.Parent.Left = leftmost.Right;

                // Присвоить крайнему левому узлу, ссылки на правого и левого потомка удаляемого узла.
                leftmost.Left  = current.Left;
                leftmost.Right = current.Right;

                if (current.Parent == null)
                {
                    Head = leftmost;

                    if (Head != null)
                    {
                        Head.Parent = null;
                    }
                }
                else
                {
                    int result = current.Parent.CompareTo(current.Value);

                    if (result > 0)
                    {
                        // Если значение родительского узла больше значения удаляемого,
                        // сделать крайнего левого потомка левым потомком родителя удаляемого узла.

                        current.Parent.Left = leftmost;
                    }
                    else if (result < 0)
                    {
                        // Если значение родительского узла, меньше чем значение удаляемого,
                        // сделать крайнего левого потомка, правым потомком родителя удаляемого узла.

                        current.Parent.Right = leftmost;
                    }
                }
            }

            if (toBalance != null)
            {
                toBalance.Balance();
            }

            else
            {
                if (Head != null)
                {
                    Head.Balance();
                }
            }
            if (toBalanceP != null)
            {
                toBalanceP.Balance();
            }

            return(true);
        }
예제 #15
0
        public static void Print <TNode>(this AvlNode <TNode> root, int topMargin = 2, int leftMargin = 2) where TNode : IComparable
        {
            if (root == null)
            {
                return;
            }
            int rootTop = Console.CursorTop + topMargin;
            var last    = new List <NodeInfo <TNode> >();
            var next    = root;

            for (int level = 0; next != null; level++)
            {
                var item = new NodeInfo <TNode> {
                    Node = next, Text = next.Value.ToString()
                };
                if (level < last.Count)
                {
                    item.StartPos = last[level].EndPos + 1;
                    last[level]   = item;
                }
                else
                {
                    item.StartPos = leftMargin;
                    last.Add(item);
                }

                if (level > 0)
                {
                    item.Parent = last[level - 1];
                    if (next == item.Parent.Node.Left)
                    {
                        item.Parent.Left = item;
                        item.EndPos      = Math.Max(item.EndPos, item.Parent.StartPos);
                    }
                    else
                    {
                        item.Parent.Right = item;
                        item.StartPos     = Math.Max(item.StartPos, item.Parent.EndPos);
                    }
                }

                next = next.Left ?? next.Right;
                for (; next == null; item = item.Parent)
                {
                    Print(item, rootTop + 2 * level);
                    if (--level < 0)
                    {
                        break;
                    }
                    if (item == item.Parent.Left)
                    {
                        item.Parent.StartPos = item.EndPos;
                        next = item.Parent.Node.Right;
                    }
                    else
                    {
                        if (item.Parent.Left == null)
                        {
                            item.Parent.EndPos = item.StartPos;
                        }
                        else
                        {
                            item.Parent.StartPos += (item.StartPos - item.Parent.EndPos) / 2;
                        }
                    }
                }
            }

            Console.SetCursorPosition(0, rootTop + 2 * last.Count - 1);
        }