Удаление элемента из двоичного бинарного дерева поиска - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Подскажите пожалуйста, как удалить элемент из двоичного бинарного дерева поиска, если имеются как левое, так и правое ответвление(очень желательно, что бы была теория и сам алгоритм)? Я уже читал теорию в другой похожей теме, но не понял её(именно ту часть, где говорится о том, что делать, если есть два ответвления). Смотрел пример на C, переписал под C#-в итоге, нужный элемент не удалился, а при последующей попытке удалить элемент с одним ответвлением получал Exception("Ссылка не ссылается на экземпляр объекта")... Вот кот, который у меня есть на данный момент(проверял-вроде бы то, что готово-то работает правильно(во всяком случае-согласно той теории, которую я читал)):
Листинг программы
  1. public BinaryTree<TYPE> DeleteData(TYPE ValueKey)
  2. {
  3. BinaryTree<TYPE> ThisData = this;
  4. if (ThisData.Value == null) throw new Exception("Невозможно удалить элемент из пустого дерева");
  5. else
  6. {
  7. Int32 CompareToResult = ThisData.Value.CompareTo(ValueKey);
  8. if (CompareToResult == 0)
  9. {
  10. if (ThisData.Right == null && ThisData.Left == null)
  11. {
  12. ThisData = ThisData.Parrent;
  13. {
  14. if (ThisData.Value.CompareTo(ValueKey) > 0) ThisData.Left = null;
  15. else if (ThisData.Value.CompareTo(ValueKey) < 0) ThisData.Right = null;
  16. }
  17. }
  18. else if (ThisData.Right == null && ThisData.Left != null)
  19. {
  20. ThisData = ThisData.Parrent;
  21. {
  22. if (ThisData.Value.CompareTo(ValueKey) > 0) ThisData.Left = ThisData.Left.Left;
  23. else if (ThisData.Value.CompareTo(ValueKey) < 0) ThisData.Right = ThisData.Right.Left;
  24. }
  25. }
  26. else if (ThisData.Right != null && ThisData.Left == null)
  27. {
  28. ThisData = ThisData.Parrent;
  29. {
  30. if (ThisData.Value.CompareTo(ValueKey) > 0) ThisData.Left = ThisData.Left.Right;
  31. else if (ThisData.Value.CompareTo(ValueKey) < 0) ThisData.Right = ThisData.Right.Right;
  32. }
  33. }
  34. else if (ThisData.Right != null && ThisData.Left != null)
  35. {
  36. }
  37. }
  38. else if (CompareToResult > 0) ThisData.Left.DeleteData(ValueKey);
  39. else if (CompareToResult < 0) ThisData.Right.DeleteData(ValueKey);
  40. }
  41. while (ThisData.Parrent != null) ThisData = ThisData.Parrent;
  42. return ThisData;
  43. }
Я читал здесь, что нужно двигаться в первой ветви до дна в левую часть, и присвоить parent левой части удаляемого элемента ссылке на левое дно Right... Пытался реализовать этот алгоритм-ничего хорошего не вышло... Вот, "не рабочий алгоритм":
Листинг программы
  1. BinaryTree<TYPE> NRight = ThisData.Right;
  2. while (NRight.Left != null) NRight = NRight.Left;
  3. BinaryTree<TYPE> NLeft = ThisData.Left;
  4. NLeft.Parrent = NRight;
  5. while (NLeft.Parrent != null) NLeft = NLeft.Parrent;
  6. ThisData = NLeft;
P.S. Сразу пишу в Windows Application варианте. Таблицу DataGridView после удаления элемента всю обновляю(т.е. сразу получаю список всех элементов, после чего именно из списка получаю всё обратно в DataGridView). Все Exception перехватываю блоком Try/Catch. Обходить мне моё дерево по заданию надо через рекурсию. Ну, я и обхожу... Вызываю этот метод удаления лишь в процессе поиска нужного элемента.

Решение задачи: «Удаление элемента из двоичного бинарного дерева поиска»

textual
Листинг программы
  1.     public void delete(int key)
  2.     {
  3.         if (this._key == key)//Если текущий элемент является удаляемым элементом
  4.         {
  5.             //Сперва, рассмотрим сценарий, где у нас нету ответвлений(удаляем лист, а не ветвь)
  6.             if (this._left == null && this._right == null)
  7.             {
  8.                 if (this._up != null)
  9.                 {
  10.                     binaryTree<T> up = this._up;
  11.                     if (up._key > key) up._left = null;
  12.                     else up._right = null;
  13.                 }
  14.                 else System.out.println("Невозможно удалить единственный элемент дерева. Воспользуйтесь функцией замены элемента");
  15.             }
  16.             //После этого, рассмотрим сценарий, где у нас есть хотя бы одно ответвление
  17.             else if ((this._left != null && this._right == null) || (this._right != null && this._left == null))
  18.             {
  19.                 binaryTree<T> _backup = (this._left != null ? this._left : this._right);
  20.                 binaryTree<T> _backup_up = this._up;
  21.                 if (_backup_up._key > key)
  22.                 {
  23.                     _backup_up._left = _backup;
  24.                     _backup._up = _backup_up;
  25.                 }
  26.                 else if (_backup_up._key < key)
  27.                 {
  28.                     _backup_up._right = _backup;
  29.                     _backup._up = _backup_up;
  30.                 }
  31.             }
  32.             //И в конце, рассмотрим сценарий, где у нас оба ответвления присутствуют/не пустые
  33.             else if (this._left != null && this._right != null)
  34.             {
  35.                 binaryTree<T> _backup = this._right;
  36.                 while (_backup._left != null) _backup = _backup._left;
  37.                 int _backup_key = _backup._key;
  38.                 T _backup_value = _backup._value;
  39.                 this.delete(_backup_key);
  40.                 this._key = _backup_key;
  41.                 this._value = _backup_value;
  42.             }
  43.         }
  44.         else if (this._key > key && this._left != null) this._left.delete(key);
  45.         else if (this._key < key && this._right != null) this._right.delete(key);
  46.     }

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

11   голосов , оценка 3.727 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы