Example #1
0
 public string Remove(int key, Tree t)                        // пошаговое удаление элемента
 {
     if (!ready)                                              // алгоритм ещё не завершился
     {
         if (t.Root.Key == key)                               // удаление корня
         {
             if (t.Root.Left == null && t.Root.Right == null) // нет потомков
             {
                 t.Root = null;
             }
             else if (t.Root.Left == null) // только правый
             {
                 t.Root       = t.Root.Right;
                 t.Root.Right = null;
                 return("Удаление корневого элемента " + key + ", он замещается правым потомком " + t.Root.Key);
             }
             else if (t.Root.Right == null) // только левый
             {
                 t.Root      = t.Root.Left;
                 t.Root.Left = null;
                 return("Удаление корневого элемента " + key + ", он замещается левым потомком " + t.Root.Key);
             }
             else // есть оба потомка
             {
                 t.Root.Color = Color.FromArgb(255, 0, 0, 255);
                 if (min_search)                       // ещё не найден замещающий элемент
                 {
                     if (min_first)                    // начало поиска минимального
                     {
                         minNode       = t.Root.Right; // ищем в правом поддереве
                         minNode.Color = Color.FromArgb(255, 255, 0, 0);
                         min_first     = false;        // больше сюда не заходим
                     }
                     return(Minimum());
                 }
                 else // найден замещающий элемент
                 {
                     int    k   = t.Minimum(t.Root.Right).Key; // находим минимального потомка
                     string res = "Удаляемый элемент " + key + " найден, его место займёт наименьший из потомков в правом поддереве " + k;
                     t.Root.Color = Color.FromArgb(255, 0, 255, 0);
                     t.Root.Right = t.Remove(t.Root.Right, k); // удаляем этого потомка
                     t.Root.Key   = k;
                     ready        = true;
                     return(res);
                 }
             }
         }
         if (currentNode == null)
         {
             ready = true;
             return("Элемент с ключом " + key + " не найден");
         }
         if (key < currentNode.Key)
         {
             currentNode.Color = Color.FromArgb(255, 255, 0, 0);
             string res = "Удаляемый элемент " + key + " меньше, чем " + currentNode.Key + ", необходмо искать в левом поддереве";
             currentNode = currentNode.Left;
             return(res);
         }
         else if (key > currentNode.Key)
         {
             currentNode.Color = Color.FromArgb(255, 255, 0, 0);
             string res = "Удаляемый элемент " + key + " больше, чем " + currentNode.Key + ", необходмо искать в правом поддереве";
             currentNode = currentNode.Right;
             return(res);
         }
         else if (currentNode.Left != null && currentNode.Right != null) // нашли удаляемый, у него есть оба потомка
         {
             currentNode.Color = Color.FromArgb(255, 0, 0, 255);
             if (min_search)                            // ещё не найден замещающий элемент
             {
                 if (min_first)                         // начало поиска минимального
                 {
                     minNode       = currentNode.Right; // ищем в правом поддереве
                     minNode.Color = Color.FromArgb(255, 255, 0, 0);
                     min_first     = false;             // больше сюда не заходим
                 }
                 return(Minimum());
             }
             else // замещающий элемент найден
             {
                 int    k   = t.Minimum(currentNode.Right).Key; // находим минимального потомка
                 string res = "Удаляемый элемент " + key + " найден, его место займёт наименьший из потомков в правом поддереве " + k;
                 currentNode.Key   = k;
                 currentNode.Color = Color.FromArgb(255, 0, 255, 0);
                 currentNode.Right = t.Remove(currentNode.Right, currentNode.Key); // удаляем этого потомка
                 ready             = true;
                 return(res);
             }
         }
         else if (currentNode.Left != null) // есть только левый потомок, он встаёт на место удаляемого
         {
             if (!found)                    // выделение цветом удаляемого элемента и его родителя
             {
                 string res = "Удаляемый элемент " + key + " найден, его место займёт левый потомок " + currentNode.Left.Key;
                 currentNode.Color      = Color.FromArgb(255, 0, 0, 255);
                 currentNode.Left.Color = Color.FromArgb(255, 0, 255, 0);
                 found = true;
                 return(res);
             }
             else // удаление элемента
             {
                 string res = "Элемент " + key + " удалён";
                 currentNode.ReplaceParentsChild(currentNode.Left);
                 currentNode = currentNode.Left;
                 ready       = true;
                 return(res);
             }
         }
         else if (currentNode.Right != null) // есть только правый потомок, он встаёт на место удаляемого
         {
             if (!found)                     // выделение цветом удаляемого элемента и его родителя
             {
                 string res = "Удаляемый элемент " + key + " найден, его место займёт правый потомок " + currentNode.Right.Key;
                 currentNode.Color       = Color.FromArgb(255, 0, 0, 255);
                 currentNode.Right.Color = Color.FromArgb(255, 0, 255, 0);
                 found = true;
                 return(res);
             }
             else // удаление элемента
             {
                 string res = "Элемент " + key + " удалён";
                 currentNode.ReplaceParentsChild(currentNode.Right);
                 currentNode = currentNode.Right;
                 ready       = true;
                 return(res);
             }
         }
         else // нет потомков, просто удаляем элемент
         {
             if (!found) // выделение цветом удаляемого элемента
             {
                 string res = "Удаляемый элемент " + key + " найден, у него нет потомков";
                 currentNode.Color = Color.FromArgb(255, 0, 255, 0);
                 found             = true;
                 return(res);
             }
             else // удаление элемента
             {
                 string res = "Элемент " + key + " удалён";
                 currentNode.ReplaceParentsChild(null);
                 ready = true;
                 found = false;
                 return(res);
             }
         }
     }
     else // алгоритм завершился, возможен перезапуск
     {
         var res = MessageBox.Show("Хотите удалить ещё один элемент?", "Удаление", MessageBoxButton.YesNo);
         if (res == MessageBoxResult.Yes)
         {
             currentNode = t.Root;
             t.Reset(t.Root);
             ready      = false;
             min_first  = true;
             min_search = true;
             found      = false;
             evRestart(this);
         }
         return("\n");
     }
 }