Рубрики
Без рубрики

Все, что вам нужно знать о структурах данных

Автор оригинала: TK.

Когда вы сначала научитесь кодируют, общее для изучения массивов в качестве «основной структуры данных».

В конце концов, вы узнаете о Хэш таблицы тоже. Если вы преследуете компьютерную науку, вы должны взять класс на структуру данных. Вы также узнаете о Связанные списки , очереди и Стеки Отказ Эти структуры данных называются «линейными» структурами данных, потому что все они имеют логический запуск и логический конец.

Когда мы начинаем узнать о деревья и Графики это может стать действительно запутанным. Мы не храним данные линейным способом. Оба данных структуры данных хранят данные определенным образом.

Этот пост должен помочь вам лучше понять структуру данных деревьев и уточнить любую путаницу, которую вы можете иметь об этом.

В этой статье мы узнаем:

  • Что такое дерево
  • Примеры деревьев
  • Его терминология и как это работает
  • Как реализовать древесные структуры в коде.

Давайте начнем это обучение.:)

Определение

При запуске программирования рекомендуется лучше понимать линейные структуры данных, чем структуры данных, такие как деревья и графики.

Деревья известны как нелинейная структура данных. Они не хранят данные линейным способом. Они организуют данные иерархически.

Давайте погрузимся в реальные образцы!

Что я имею в виду, когда я говорю в иерархическом смысле?

Представьте себе семейное дерево с отношениями со всего поколения: бабушка и дедушка, родителей, детей, братьев и т. Д. Мы обычно организуем семейные деревья иерархически.

Вышеупомянутый рисунок – это мое семейное дерево. Тосико, акиказу, Хитоми, и Такеми мои бабушка и дедушка.

Тошиаки и Джулиана мои родители.

TK, Yuji, Bruno и Kaio Дети моих родителей (я и моих братьев).

Структура организации является еще одним примером иерархии.

В HTML модель объекта документа (DOM) работает как дерево.

HTML Тег содержит другие теги. У нас есть голова Тег и Тело тег. Эти теги содержит определенные элементы. голова Тег имеет Мета и Название Теги. Тело TAG имеет элементы, которые показывают в пользовательском интерфейсе, например, H1 , А , Ли , так далее.

Техническое определение

А дерево это коллекция объектов под названием узлы Отказ Узлы связаны края Отказ Каждый Узел содержит ценность или данные и это может или не может иметь Детский узел Отказ

Первый узел из дерево называется корень Отказ Если это Корневой узел подключен другим Узел , корень тогда а Родительский узел и связанные Узел это ребенок Отказ

Все Узлы деревьев связаны ссылками под названием края Отказ Это важная часть деревья потому что это управляет отношениями между узлы Отказ

Листья последние узлы на дерево. Они узлы без детей. Как настоящие деревья, у нас есть корень , филиалы и, наконец, Листья Отказ

Другие важные концепции, чтобы понять, что Высота и Глубина Отказ

Высота из дерево это длина самый длинный путь к лист Отказ

Глубина из Узел это длина пути к его корень Отказ

Краткое содержание терминологии

  • Корень самый верх Узел из дерево
  • Край ссылка между двумя узлы
  • Ребенок это Узел у этого есть родительский узел
  • Родитель это Узел у этого есть край к узел ребенка
  • Лист это Узел Это не имеет Детский узел В дерево
  • Высота это длина самый длинный путь к лист
  • Глубина это длина пути к его корень

Бинарные деревья

Теперь мы обсудим конкретный тип дерево Отказ Мы называем это Бинарное дерево Отказ

Итак, давайте посмотрим на пример Бинарное дерево Отказ

Давайте код бинарного дерева

Первое, что нам нужно иметь в виду, когда мы реализуем Бинарное дерево Это то, что это коллекция узлы Отказ Каждый Узел имеет три атрибута: ценность , left_child и right_child Отказ

Как мы реализуем простой Бинарное дерево которые инициализируются с этими тремя свойствами?

Давайте взглянем.

class BinaryTree:
    def __init__(self, value):
        self.value = value
        self.left_child = None
        self.right_child = None

Вот. Наше Бинарное дерево класс.

Когда мы создали объект, мы передаем ценность (данные узла) в качестве параметра. Посмотри на left_child и right_child Отказ Оба устанавливаются на Нет Отказ

Почему?

Потому что когда мы создаем наши Узел у него нет детей. У нас просто Узел данных Отказ

Давайте тестируем это:

tree = BinaryTree('a')
print(tree.value) # a
print(tree.left_child) # None
print(tree.right_child) # None

Вот и все.

Мы можем пройти строкаА «Как ценность нашему Узел двоичного дерева Отказ Если мы распечатаем ценность , left_child и right_child , мы видим значения.

Давайте перейдем к детали вставки. Что нам нужно сделать здесь?

Мы реализуем способ вставить новый Узел к правильно и к левый Отказ

Вот правила:

  • Если текущий Узел не имеет Левый ребенок мы просто создаем новый Узел и установите его на текущий узел left_child Отказ
  • Если у него есть Левый ребенок Мы создаем новый узел и поместите его в текущий Левый ребенок место. Выделить это Левый узел ребенка к новому узлу Левый ребенок Отказ

Давайте нарисуем это.:)

Вот код:

def insert_left(self, value):
    if self.left_child == None:
        self.left_child = BinaryTree(value)
    else:
        new_node = BinaryTree(value)
        new_node.left_child = self.left_child
        self.left_child = new_node

Опять же, если текущий узел не имеет Левый ребенок Мы просто создаем новый узел и установили его на текущий узел left_child Отказ Или мы создаем новый узел и поместите его в текущий Левый ребенок место. Выделить это Левый узел ребенка к новому узлу Левый ребенок Отказ

И мы делаем то же самое, чтобы вставить Правый дочерний узел Отказ

def insert_right(self, value):
    if self.right_child == None:
        self.right_child = BinaryTree(value)
    else:
        new_node = BinaryTree(value)
        new_node.right_child = self.right_child
        self.right_child = new_node

Сделанный.:)

Но не совсем. Нам все еще нужно проверить это.

Давайте построим следующее дерево :

Подвести иллюстрировать иллюстрацию этого дерева:

  • А Узел будет корень нашего бинарное дерево
  • А Левый ребенок это B узел
  • А Правый ребенок это C узел
  • B Правый ребенок это D Узел ( B Узел Нет Левый ребенок )
  • C Левый ребенок это е узел
  • C Правый ребенок это F узел
  • оба е и F узлы не иметь детей

Так вот код для дерево :

a_node = BinaryTree('a')
a_node.insert_left('b')
a_node.insert_right('c')

b_node = a_node.left_child
b_node.insert_right('d')

c_node = a_node.right_child
c_node.insert_left('e')
c_node.insert_right('f')

d_node = b_node.right_child
e_node = c_node.left_child
f_node = c_node.right_child

print(a_node.value) # a
print(b_node.value) # b
print(c_node.value) # c
print(d_node.value) # d
print(e_node.value) # e
print(f_node.value) # f

Вставка выполняется.

Теперь мы должны думать о дерево обход.

У нас есть Два варианта Вот: Глубинный поиск (DFS) и Широк-первый поиск (BFS) Отказ

  • DFS «Это алгоритм для прохождения или поиска структуры данных деревьев. Один запускается в корне и исследуется как можно дальше вдоль каждого ветви перед возвратом. Википедия
  • BFS «Это алгоритм для прохождения или поиска структуры дерева. Это начинается в корне дерева и сначала исследует соседние узлы, прежде чем перейти на соседей следующего уровня». Википедия

Так что давайте погрузимся в каждый тип обхода дерева.

Глубинный поиск (DFS)

DFS Исследует путь весь путь к листу перед обратно и исследуя другой путь. Давайте посмотрим на пример с этим типом обхода.

Результат для этого алгоритма составит 1-2-3-4-5-6-7.

Почему?

Давайте сломаемся.

  1. Начните в корень (1). Распечатать его.

2. Перейдите к Левый ребенок (2). Распечатать его.

3. Тогда иди к Левый ребенок (3). Распечатать его. (Это узел нет детей)

4. Вернуться и пойти Правый ребенок (4). Распечатать его. (Это узел нет детей)

5. Вернуться к корень Узел и перейти к Правый ребенок (5). Распечатать его.

6. Перейдите к Левый ребенок (6). Распечатать его. (Это узел нет детей)

7. Вернуться и перейдите к Правый ребенок (7). Распечатать его. (Это узел нет детей)

8. сделано.

Когда мы идем глубоко в лист и обратно, это называется DFS алгоритм.

Теперь, когда мы знакомы с этим алгоритмом обхода, мы обсудим типы DFS : Предварительный заказ , по порядку и пост порядка Отказ

Предзаказ

Это именно то, что мы сделали в приведенном выше примере.

  1. Распечатайте значение Узел Отказ
  2. Перейти к Левый ребенок и распечатать его. Это если, и только если у него есть Левый ребенок Отказ
  3. Перейти к Правый ребенок и распечатать его. Это если, и только если у него есть Правый ребенок Отказ
def pre_order(self):
    print(self.value)

    if self.left_child:
        self.left_child.pre_order()

    if self.right_child:
        self.right_child.pre_order()

Чтобы

Результат алгоритма в заказах для этого дерево Пример 3-2-4-1-6-5-7.

Влево сначала, средняя секунда, и вправо последнее.

Теперь давайте кодируем это.

def in_order(self):
    if self.left_child:
        self.left_child.in_order()

    print(self.value)

    if self.right_child:
        self.right_child.in_order()
  1. Перейти к Левый ребенок и распечатать его. Это если, и только если у него есть Левый ребенок Отказ
  2. Распечатать Узел значение
  3. Перейти к Правый ребенок и распечатать его. Это если, и только если у него есть Правый ребенок Отказ

Пост порядка

Результат Почтовый заказ алгоритм для этого дерево Пример составляет 3-4-2-6-7-5-1.

Влево сначала, вправо второй, а середина последнего.

Давайте кодируем это.

def post_order(self):
    if self.left_child:
        self.left_child.post_order()

    if self.right_child:
        self.right_child.post_order()

    print(self.value)
  1. Перейти к Левый ребенок и распечатать его. Это если, и только если у него есть Левый ребенок Отказ
  2. Перейти к Правый ребенок и распечатать его. Это если, и только если у него есть Правый ребенок Отказ
  3. Распечатать Узел значение

Широк-первый поиск (BFS)

BFS алгоритм пересекает дерево Уровень на уровне и глубину глубиной.

Вот пример, который помогает лучше объяснить этот алгоритм:

Итак, мы превышаем уровень по уровню. В этом примере результат составляет 1-2-5-3-4-6-7.

  • Уровень/Глубина 0: Только Узел со значением 1
  • Уровень/глубина 1: узлы со значениями 2 и 5
  • Уровень/Глубина 2: узлы со значениями 3, 4, 6 и 7

Теперь давайте кодируем это.

def bfs(self):
    queue = Queue()
    queue.put(self)

    while not queue.empty():
        current_node = queue.get()
        print(current_node.value)

        if current_node.left_child:
            queue.put(current_node.left_child)

        if current_node.right_child:
            queue.put(current_node.right_child)

Для реализации BFS алгоритм, мы используем очередь Структура данных, чтобы помочь.

Как это работает?

Вот объяснение.

  1. Сначала добавьте корень Узел в очередь с поставить метод.
  2. Итерация, пока очередь не пусто.
  3. Получить первый Узел В очередь и затем распечатайте его значение.
  4. Добавьте оба левый и правильно дети в очередь (Если текущий узел имеет дети ).
  5. Сделанный. Мы распечатаем значение каждого Узел, Уровень на уровне, с нашим очередь помощник.

Двоичное дерево поиска

Важное свойство Двоичное поиск деревьев это то значение Двоичное поиск деревьев Узел больше, чем значение потомства его Левый ребенок , но меньше, чем стоимость потомства его правильный ребенок.

Вот разбивка вышеуказанного иллюстрации:

  • А перевернут. подделка 7-5-8-6 должны быть на правой стороне, а подделка 2-1-3 должно быть слева.
  • B единственный правильный вариант. Это удовлетворяет Двоичное поиск деревьев имущество.
  • C имеет одну проблему: Узел С ценностью 4. Это должно быть на левой стороне корень Потому что это меньше 5.

Давайте код бинарного поиска!

Теперь пришло время кодировать!

Что мы здесь увидим? Мы вставим новые узлы, поиск стоимости, удаления узлов и баланс дерево Отказ

Давайте начнем.

Вставка: добавление новых узлов на наше дерево

Представьте, что у нас пустое дерево И мы хотим добавить новые узлы Со следующими значениями в этом порядке: 50, 76, 21, 4, 32, 100, 64, 52.

Первое, что нам нужно знать, это если 50 – это корень нашего дерева.

Теперь мы можем начать вставлять Узел По Узел Отказ

  • 76 больше 50, поэтому вставьте 76 на правую сторону.
  • 21 меньше 50, поэтому вставьте 21 на левую сторону.
  • 4 меньше 50. Узел С стоимостью 50 имеет Левый ребенок 21. С 4 меньше 21, вставьте его на левую сторону этого Узел Отказ
  • 32 меньше 50. Узел С стоимостью 50 имеет Левый ребенок 21. С 32 больше 21, вставьте 32 на правую сторону этого Узел Отказ
  • 100 больше 50. Узел С стоимостью 50 имеет Правый ребенок 76. С 100 больше 76, вставьте 100 на правую сторону этого Узел Отказ
  • 64 больше 50. Узел С стоимостью 50 имеет Правый ребенок 76. С 64 меньше 76, вставьте 64 на левую сторону этого Узел Отказ
  • 52 больше 50. Узел С стоимостью 50 имеет Правый ребенок 76. С 52 меньше 76, Узел С стоимостью 76 имеет Левый ребенок 64. 52 меньше 64, поэтому вставьте 54 на левую сторону этого Узел Отказ

Вы замечаете узор здесь?

Давайте сломаемся.

  1. Это новый Узел значение больше или меньше текущего Узел ?
  2. Если значение нового Узел больше текущего Узел, Перейти вправо подделка Отказ Если текущий Узел не имеет Правый ребенок , вставьте его там или иначе обратно на шаг # 1.
  3. Если значение нового Узел меньше текущего Узел Перейти к левому подделка Отказ Если текущий Узел не имеет Левый ребенок , вставьте его там или иначе обратно на шаг # 1.
  4. Мы не справились с особыми случаями здесь. Когда значение нового Узел равно текущей стоимостью Узел, Использовать правило № 3. Рассмотрите возможность вставки равных значений в левую сторону подделка Отказ

Теперь давайте кодируем это.

class BinarySearchTree:
    def __init__(self, value):
        self.value = value
        self.left_child = None
        self.right_child = None

    def insert_node(self, value):
        if value <= self.value and self.left_child:
            self.left_child.insert_node(value)
        elif value <= self.value:
            self.left_child = BinarySearchTree(value)
        elif value > self.value and self.right_child:
            self.right_child.insert_node(value)
        else:
            self.right_child = BinarySearchTree(value)

Кажется очень простым.

Мощная часть этого алгоритма является частью рекурсионной части, которая находится на линии 9 и линия 13. Обе линии кода вызывают insert_node метод и использовать его для его левый и правильно дети , соответственно. Линии 11 и 15 те, которые делают вставку для каждого ребенок Отказ

Давайте искать значение узла … или нет …

Алгоритм, который мы будем строить сейчас, речь ищет поиск. Для заданного значения (целое число) мы скажем, если наше Двоичное поиск деревьев делает или не имеет этого значения.

Важным элементом следует отметить, как мы определили дерево Алгоритм вставки . Отказ Сначала у нас есть наш корень Узел Отказ Все левые подделка узлы будет иметь меньшие значения, чем корень Узел Отказ И все правильно подделка узлы будут иметь значения больше, чем корень Узел Отказ

Давайте посмотрим на пример.

Представьте, что у нас есть этот дерево Отказ

Теперь мы хотим знать, есть ли у нас узел на основе стоимости 52.

Давайте сломаемся.

  1. Начнем с корень Узел Как наш текущий Узел Отказ Данное значение меньшее, чем текущий Узел значение? Если да, то мы будем искать его слева подделка Отказ
  2. Данное значение превышает текущий Узел значение? Если да, то мы будем искать его справа подделка Отказ
  3. Если правила № 1 и № 2 являются ложными, мы можем сравнить текущий Узел значение и заданное значение, если они равны. Если сравнение возвращает правда Тогда мы можем сказать: «Да! Наше Дерево имеет данную ценность», иначе мы говорим: «Ное нет».

Теперь давайте кодируем это.

class BinarySearchTree:
    def __init__(self, value):
        self.value = value
        self.left_child = None
        self.right_child = None

    def find_node(self, value):
        if value < self.value and self.left_child:
            return self.left_child.find_node(value)
        if value > self.value and self.right_child:
            return self.right_child.find_node(value)

        return value == self.value

Давайте сломаем код:

  • Линии 8 и 9 падают под правилом № 1.
  • Линии 10 и 11 подпадают под правилом № 2.
  • Линия 13 падает под правилом № 3.

Как мы тестируем это?

Давайте создадим наш Двоичное поиск деревьев Инициализация корень Узел со значением 15.

bst = BinarySearchTree(15)

И теперь мы вставим много новых узлы Отказ

bst.insert_node(10)
bst.insert_node(8)
bst.insert_node(12)
bst.insert_node(20)
bst.insert_node(17)
bst.insert_node(25)
bst.insert_node(19)

Для каждого вставленного Узел мы проверим, если наш Find_node Метод действительно работает.

print(bst.find_node(15)) # True
print(bst.find_node(10)) # True
print(bst.find_node(8)) # True
print(bst.find_node(12)) # True
print(bst.find_node(20)) # True
print(bst.find_node(17)) # True
print(bst.find_node(25)) # True
print(bst.find_node(19)) # True

Да, это работает для этих заданных ценностей! Давайте тестируем на значение, которое не существует в наших Двоичное поиск деревьев Отказ

print(bst.find_node(0)) # False

Ах, да.

Наш поиск сделан.

Удаление: удаление и организация

Удаление – это более сложный алгоритм, потому что нам нужно обрабатывать разные случаи. Для заданного значения нам нужно удалить Узел с этим значением. Представьте себе следующие сценарии для этого Узел : у него нет дети имеет один ребенок или имеет два дети Отказ

  • Сценарий # 1 : A Узел без дети ( Лист Узел ).
#        |50|                              |50|
#      /      \                           /    \
#    |30|     |70|   (DELETE 20) --->   |30|   |70|
#   /    \                                \
# |20|   |40|                             |40|

Если Узел Мы хотим удалить нет детей, мы просто удаляем его. Алгоритм не нужно реорганизовать дерево Отказ

  • Сценарий # 2 : A Узел С одним ребенком ( левый или правый ребенок).
#        |50|                              |50|
#      /      \                           /    \
#    |30|     |70|   (DELETE 30) --->   |20|   |70|
#   /            
# |20|

В этом случае наш алгоритм должен сделать родителя Узел Укажите на ребенок узел. Если Узел это Левый ребенок Мы делаем родителя Левый ребенок Укажите на ребенок Отказ Если Узел это Правый ребенок его родителя, мы делаем родителя Правый ребенок Укажите на ребенок Отказ

  • Сценарий № 3 : A Узел с двумя детьми.
#        |50|                              |50|
#      /      \                           /    \
#    |30|     |70|   (DELETE 30) --->   |40|   |70|
#   /    \                             /
# |20|   |40|                        |20|

Когда Узел Есть 2 детей, нам нужно найти Узел С минимальным значением, начиная с Узел ‘s Правый ребенок Отказ Мы поставим это Узел с минимальным значением в месте Узел Мы хотим удалить.

Пришло время кодировать.

def remove_node(self, value, parent):
    if value < self.value and self.left_child:
        return self.left_child.remove_node(value, self)
    elif value < self.value:
        return False
    elif value > self.value and self.right_child:
        return self.right_child.remove_node(value, self)
    elif value > self.value:
        return False
    else:
        if self.left_child is None and self.right_child is None and self == parent.left_child:
            parent.left_child = None
            self.clear_node()
        elif self.left_child is None and self.right_child is None and self == parent.right_child:
            parent.right_child = None
            self.clear_node()
        elif self.left_child and self.right_child is None and self == parent.left_child:
            parent.left_child = self.left_child
            self.clear_node()
        elif self.left_child and self.right_child is None and self == parent.right_child:
            parent.right_child = self.left_child
            self.clear_node()
        elif self.right_child and self.left_child is None and self == parent.left_child:
            parent.left_child = self.right_child
            self.clear_node()
        elif self.right_child and self.left_child is None and self == parent.right_child:
            parent.right_child = self.right_child
            self.clear_node()
        else:
            self.value = self.right_child.find_minimum_value()
            self.right_child.remove_node(self.value, self)

        return True
  1. Первый : Обратите внимание на параметры ценность и родитель Отказ Мы хотим найти Узел Это имеет это ценность и Узел Родитель важен для удаления Узел Отказ
  2. Второй : Обратите внимание на возвращаемое значение. Наш алгоритм вернет логическое значение. Это возвращает Правда Если он найдет Узел и удаляет это. В противном случае это вернется Ложь Отказ
  3. От линии 2 до линии 9 : Мы начинаем поиск Узел что имеет ценность что мы ищем. Если ценность меньше, чем Текущий Nodevalue мы идем к левый поддерево рекурсивно (если и только если, нынешний узел нынешний узел ). Если ценность больше, иди к правый поддерева рекурсивно. Линия 10 : Мы начинаем думать о
  4. Удалить алгоритм. От линии 11 до линии 13 : Мы охватываем
  5. Узел без дети и это Левый ребенок от его родитель Отказ Мы удаляем Узел Установив родитель ‘s Левый ребенок к Нет Отказ Строки 14 и 15 : Мы охватываем
  6. Узел без дети и это Правый ребенок от этого родитель Отказ Мы удаляем Узел Установив родитель ‘s Правый ребенок к Нет Отказ Прозрачный узел Метод : Я покажу
  7. Clear_node код ниже. Он устанавливает узлы Левый ребенок, правый ребенок и его ценность к Нет Отказ От линии 16 до линии 18 : Мы охватываем
  8. Узел только с одним ребенок ( Левый ребенок ), и это Левый ребенок от этого родитель Отказ Мы устанавливаем родитель ‘s Левый ребенок к Узел ‘s Левый ребенок (единственный ребенок имеет). От линии 19 до линии 21 : Мы охватываем
  9. Узел только с одним ребенок ( Левый ребенок ), и это Правый ребенок от его родитель Отказ Мы устанавливаем родитель ‘s Правый ребенок к Узел ‘s Левый ребенок (единственный ребенок имеет). От линии 22 до линии 24 : Мы охватываем
  10. Узел только с одним ребенок ( Правильный ребенок ), и это Левый ребенок от его родитель Отказ Мы устанавливаем родитель ‘s Левый ребенок к Узел ‘s Правый ребенок (единственный ребенок имеет). От линии 25 до линии 27 : Мы охватываем
  11. Узел только с одним ребенок ( Правильный ребенок ), и это Правый ребенок от его родитель Отказ Мы устанавливаем родитель ‘s Правый ребенок к Узел ‘s Правый ребенок (единственный ребенок имеет). От линии 28 до линии 30 : Мы охватываем
  12. Узел с обоими левый и правильно дети. Мы получаем Узел С наименьшим ценность (код показан ниже) и установить его на ценность из Текущий узел Отказ Закончить его, удалив самых маленьких Узел Отказ Линия 32 : Если мы найдем
  13. Узел Мы ищем, это необходимо вернуть Правда Отказ От линии 11 до линии 31, мы обращаемся к этому случаю. Так что просто верните Правда вот и все.
  • Использовать Clear_node Метод: установить Нет Значение всем трем атрибутам – ( Value , left_child и right_child )
def clear_node(self):
    self.value = None
    self.left_child = None
    self.right_child = None
  • Использовать find_minimum_value Метод: Перейдите вниз к левому. Если мы не можем найти больше узлов, мы нашли наименьшего.
def find_minimum_value(self):
    if self.left_child:
        return self.left_child.find_minimum_value()
    else:
        return self.value

Теперь давайте проверим это.

Мы будем использовать это дерево Чтобы проверить нашу Remove_node алгоритм.

#        |15|
#      /      \
#    |10|     |20|
#   /    \    /    \
# |8|   |12| |17| |25|
#              \
#              |19|

Давайте удалим Узел с ценность 8. Это Узел без ребенка.

print(bst.remove_node(8, None)) # True
bst.pre_order_traversal()

#     |15|
#   /      \
# |10|     |20|
#    \    /    \
#   |12| |17| |25|
#          \
#          |19|

Теперь давайте удалим Узел с ценность 17. Это Узел с одним ребенком.

print(bst.remove_node(17, None)) # True
bst.pre_order_traversal()

#        |15|
#      /      \
#    |10|     |20|
#       \    /    \
#      |12| |19| |25|

Наконец, мы удалим Узел с двумя детьми. Это корень нашего дерево Отказ

print(bst.remove_node(15, None)) # True
bst.pre_order_traversal()

#        |19|
#      /      \
#    |10|     |20|
#        \        \
#        |12|     |25|

Тесты теперь сделаны.:)

Это все сейчас!

Мы многому научились здесь.

Поздравляю с заканчиванием этого плотного контента. Очень сложно понять концепцию, которую мы не знаем. Но ты сделал это.:)

Это еще один шаг вперед в моем путешествии к алгоритмам обучения и овладевания и структур данных. Вы можете увидеть документацию моего полного путешествия здесь на моем Ренессанс Разработчик Публикация Отказ

Веселитесь, продолжайте учиться и кодировать.

Мой Twitter & Github Отказ ☺.

Дополнительные ресурсы