/// <summary> /// Удаляет узел с заданным следом, только для использования внутри основного метода Delete.....(). /// Возвращает ссылку на новый узел (старый удаляется) /// </summary> /// <param name="currentNode"></param> /// <param name="trace"></param> /// <returns></returns> private Node <T> DeleteThisTrace(Node <T> currentNode, string trace) { if (currentNode != null) { int path = Subroutines.CompareTraces(currentNode.Trace, trace); if (path == -1) { currentNode.LeftChild = DeleteThisTrace(currentNode.LeftChild, trace); } else if (path == 1) { currentNode.RightChild = DeleteThisTrace(currentNode.RightChild, trace); } else if (path == -2) // здесь по-хорошему бы стек почистить да выйти из метода { return(currentNode); } else if (path == 0) { if (currentNode.RightChild == null) { currentNode = currentNode.LeftChild; // здесь можно поставить оператор return } else { Node <T> currentNodeLeftChild = currentNode.LeftChild; Node <T> currentNodeRightChild = FindMinNode(currentNode.RightChild, ref currentNode); // в currentNode окажется минимальный элемент из правого поддерева currentNode.LeftChild = currentNodeLeftChild; currentNode.RightChild = currentNodeRightChild; } } } else { throw new InvalidOperationException("Узел с таким следом не найден"); } currentNode = Balance(currentNode); return(currentNode); }
static void Main(string[] args) { bool goOut; bool rewriteOutput = true; AVLTree <int> avlTree = new AVLTree <int>(); do { goOut = false; switch (Subroutines.PrintMenu()) { // // c - создать дерево и заполнить его случайными величинами // case 'c': { int numberOfNodes; do { do { Console.WriteLine("\nУкажите количество узлов в дереве (не более 100 и не менее 1)"); } while (!Int32.TryParse(Console.ReadLine(), out numberOfNodes)); } while (numberOfNodes < 1 || numberOfNodes > 100); Random random = new Random(); for (int i = 0; i < numberOfNodes; i++) { avlTree.Add(random.Next(-50, 50), random.Next(-50, 50)); } random = null; Subroutines.SaveTreeInFile(avlTree, "input.dat"); if (rewriteOutput == true) { rewriteOutput = false; File.Delete("output.dat"); } StreamWriter writer = new StreamWriter("output.dat", true); writer.WriteLine("==============================================================================="); writer.WriteLine("После добавления узлов получилось дерево следующего вида\n"); writer.WriteLine("==============================================================================="); writer.Close(); Subroutines.AddFromFileToFile("input.dat", "output.dat"); try { Subroutines.AddLinksTableToFile(avlTree, "output.dat"); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } Console.WriteLine("\nДобавление прошло успешно, нажмите что-нибудь!"); Console.ReadKey(); break; } // // b - добавить элементы в дерево вручную // case 'b': { int numberOfNodes; int nodeKey; do { do { Console.WriteLine("\nУкажите количество узлов в дереве, которое хотите добавить (не более 10 и не менее 1)"); } while (!Int32.TryParse(Console.ReadLine(), out numberOfNodes)); } while (numberOfNodes < 1 || numberOfNodes > 10); for (int i = 0; i < numberOfNodes; i++) { do { Console.WriteLine("Число №" + i + " = "); } while (Int32.TryParse(Console.ReadLine(), out nodeKey) == false); avlTree.Add(nodeKey, nodeKey); } Subroutines.SaveTreeInFile(avlTree, "input.dat"); if (rewriteOutput == true) { rewriteOutput = false; File.Delete("output.dat"); } StreamWriter writer = new StreamWriter("output.dat", true); writer.WriteLine("==============================================================================="); writer.WriteLine("После добавления узлов получилось дерево следующего вида\n"); writer.WriteLine("==============================================================================="); writer.Close(); Subroutines.AddFromFileToFile("input.dat", "output.dat"); try { Subroutines.AddLinksTableToFile(avlTree, "output.dat"); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } Console.WriteLine("\nДобавление прошло успешно, нажмите что-нибудь!"); Console.ReadKey(); break; } // // * d - удалить узел с заданным следом // case 'd': { string trace; do { Console.Write("Введите интересующий вас след: "); trace = Console.ReadLine(); } while (!Subroutines.IsTrace(trace)); try { avlTree.DeleteThisTrace(trace); Console.WriteLine("Удаление прошло успешно. Нажмите что-нибудь"); Console.ReadKey(); } catch (NullReferenceException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } catch (FormatException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } catch (InvalidOperationException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } catch (Exception e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } StreamWriter writer = new StreamWriter("output.dat", true); if (rewriteOutput == true) { rewriteOutput = false; File.Delete("output.dat"); } writer.WriteLine("==============================================================================="); writer.WriteLine("После удаления узла со следом " + trace + " получилось дерево следующего вида\n"); writer.WriteLine("==============================================================================="); writer.Close(); try { Subroutines.AddLinksTableToFile(avlTree, "output.dat"); } catch (FileNotFoundException e) { Console.WriteLine(e.Message); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } break; } // // p - показать дерево (сделать обход, без связей) // case 'p': if (avlTree.ShowTree() == false) { Console.WriteLine("Дерево пусто! Нажмите что-нибудь"); Console.ReadKey(); } else { Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } break; // // r - показать таблицу связей дерева // case 'r': if (avlTree.ShowTreeLinks() == false) { Console.WriteLine("Дерево пусто! Нажмите что-нибудь"); Console.ReadKey(); } else { Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } break; // // h - Получить высоту дерева // case 'h': Console.WriteLine(" Высота данного дерева = " + avlTree.Height); Console.ReadKey(); break; // // v - получить информацию о корне // case 'v': Console.WriteLine("\n"); avlTree.GetRootInfo(); Console.ReadKey(); break; // // * n - установить правильные следы в дереве // case 'n': { if (avlTree.PutTrace() == false) { Console.WriteLine("Невозможно восстановить следы"); Console.WriteLine("\n===========Нажмите что-нибудь==========="); Console.ReadKey(); } break; } // // ESC - выход // case (char)27: goOut = true; break; } } while (goOut == false); }