// Метод добавлет новый узел public void Insert(T value) { // Вариант 1: Дерево пустое - создание корня дерева if (Head == null) { Head = new AvlNode <T>(value, null, this); } // Вариант 2: Дерево не пустое - найти место для добавление нового узла. else { AddTo(Head, value); } Count++; }
} //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
} //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; } }
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
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(); }
private void LeftRotation() { // До // 12(this) // \ // 15 // \ // 25 // // После // 15 // / \ // 12 25 // Сделать правого потомка новым корнем дерева. AvlNode <TNode> newRoot = Right; ReplaceRoot(newRoot); // Поставить на место правого потомка - левого потомка нового корня. Right = newRoot.Left; // Сделать текущий узел - левым потомком нового корня. newRoot.Left = this; }
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
// Алгоритм рекурсивного добавления нового узла в дерево. 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(); }
public void Reset() { _right = _root; _action = _root == null ? Action.End : Action.Right; }
public AvlNodeEnumerator(AvlNode <@int, @string> root) { _right = _root = root; _action = _root == null ? Action.End : Action.Right; }
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(); }
AvlNode <TNode> _right; // правый потомок #region Конструктор public AvlNode(TNode value, AvlNode <TNode> parent, AvlTree <TNode> tree) { Value = value; Parent = parent; _tree = tree; }
} //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
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); }
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); }