Когда вы сначала научитесь кодируют, общее для изучения массивов в качестве «основной структуры данных».
В конце концов, вы узнаете о Хэш таблицы тоже. Если вы преследуете компьютерную науку, вы должны взять класс на структуру данных. Вы также узнаете о Связанные списки , очереди и Стеки Отказ Эти структуры данных называются «линейными» структурами данных, потому что все они имеют логический запуск и логический конец.
Когда мы начинаем узнать о деревья и Графики это может стать действительно запутанным. Мы не храним данные линейным способом. Оба данных структуры данных хранят данные определенным образом.
Этот пост должен помочь вам лучше понять структуру данных деревьев и уточнить любую путаницу, которую вы можете иметь об этом.
В этой статье мы узнаем:
- Что такое дерево
- Примеры деревьев
- Его терминология и как это работает
- Как реализовать древесные структуры в коде.
Давайте начнем это обучение.:)
Определение
При запуске программирования рекомендуется лучше понимать линейные структуры данных, чем структуры данных, такие как деревья и графики.
Деревья известны как нелинейная структура данных. Они не хранят данные линейным способом. Они организуют данные иерархически.
Давайте погрузимся в реальные образцы!
Что я имею в виду, когда я говорю в иерархическом смысле?
Представьте себе семейное дерево с отношениями со всего поколения: бабушка и дедушка, родителей, детей, братьев и т. Д. Мы обычно организуем семейные деревья иерархически.
Вышеупомянутый рисунок – это мое семейное дерево. Тосико, акиказу, Хитоми, и Такеми мои бабушка и дедушка.
Тошиаки и Джулиана мои родители.
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). Распечатать его.
2. Перейдите к Левый ребенок (2). Распечатать его.
3. Тогда иди к Левый ребенок (3). Распечатать его. (Это узел нет детей)
4. Вернуться и пойти Правый ребенок (4). Распечатать его. (Это узел нет детей)
5. Вернуться к корень Узел и перейти к Правый ребенок (5). Распечатать его.
6. Перейдите к Левый ребенок (6). Распечатать его. (Это узел нет детей)
7. Вернуться и перейдите к Правый ребенок (7). Распечатать его. (Это узел нет детей)
8. сделано.
Когда мы идем глубоко в лист и обратно, это называется DFS алгоритм.
Теперь, когда мы знакомы с этим алгоритмом обхода, мы обсудим типы DFS : Предварительный заказ , по порядку и пост порядка Отказ
Предзаказ
Это именно то, что мы сделали в приведенном выше примере.
- Распечатайте значение
УзелОтказ - Перейти к
Левый ребеноки распечатать его. Это если, и только если у него естьЛевый ребенокОтказ - Перейти к
Правый ребеноки распечатать его. Это если, и только если у него естьПравый ребенокОтказ
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()- Перейти к
Левый ребеноки распечатать его. Это если, и только если у него естьЛевый ребенокОтказ - Распечатать
Узелзначение - Перейти к
Правый ребеноки распечатать его. Это если, и только если у него естьПравый ребенокОтказ
Пост порядка
Результат Почтовый заказ алгоритм для этого дерево Пример составляет 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)- Перейти к
Левый ребеноки распечатать его. Это если, и только если у него естьЛевый ребенокОтказ - Перейти к
Правый ребеноки распечатать его. Это если, и только если у него естьПравый ребенокОтказ - Распечатать
Узелзначение
Широк-первый поиск (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 алгоритм, мы используем очередь Структура данных, чтобы помочь.
Как это работает?
Вот объяснение.
- Сначала добавьте
кореньУзелвочередьспоставитьметод. - Итерация, пока
очередьне пусто. - Получить первый
УзелВочередьи затем распечатайте его значение. - Добавьте оба
левыйиправильнодетивочередь(Если текущийузелимеетдети). - Сделанный. Мы распечатаем значение каждого
Узел,Уровень на уровне, с нашимочередьпомощник.
Двоичное дерево поиска
Важное свойство Двоичное поиск деревьев это то значение Двоичное поиск деревьев Узел больше, чем значение потомства его Левый ребенок , но меньше, чем стоимость потомства его правильный ребенок. “
Вот разбивка вышеуказанного иллюстрации:
- А перевернут.
подделка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. - Если значение нового
Узелменьше текущегоУзелПерейти к левомуподделкаОтказ Если текущийУзелне имеетЛевый ребенок, вставьте его там или иначе обратно на шаг # 1. - Мы не справились с особыми случаями здесь. Когда значение нового
Узелравно текущей стоимостьюУзел,Использовать правило № 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 являются ложными, мы можем сравнить текущий
Узелзначение и заданное значение, если они равны. Если сравнение возвращаетправдаТогда мы можем сказать: «Да! НашеДеревоимеет данную ценность», иначе мы говорим: «Ное нет».
Теперь давайте кодируем это.
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- Первый : Обратите внимание на параметры
ценностьиродительОтказ Мы хотим найтиУзелЭто имеет этоценностьиУзелРодитель важен для удаленияУзелОтказ - Второй : Обратите внимание на возвращаемое значение. Наш алгоритм вернет логическое значение. Это возвращает
ПравдаЕсли он найдетУзели удаляет это. В противном случае это вернетсяЛожьОтказ - От линии 2 до линии 9 : Мы начинаем поиск
Узелчто имеетценностьчто мы ищем. Еслиценностьменьше, чемТекущий Nodevalueмы идем клевый поддереворекурсивно (если и только если, нынешний узелнынешний узел). Еслиценностьбольше, иди кправый поддереварекурсивно.Линия 10: Мы начинаем думать о - Удалить алгоритм.
От линии 11 до линии 13: Мы охватываем - Узел без
детии этоЛевый ребенокот егородительОтказ Мы удаляемУзелУстановивродитель‘sЛевый ребеноккНетОтказСтроки 14 и 15: Мы охватываем - Узел без
детии этоПравый ребенокот этогородительОтказ Мы удаляемУзелУстановивродитель‘sПравый ребеноккНетОтказПрозрачный узел Метод: Я покажу - Clear_node код ниже. Он устанавливает узлы
Левый ребенок, правый ребеноки егоценностькНетОтказОт линии 16 до линии 18: Мы охватываем - Узел только с одним
ребенок(Левый ребенок), и этоЛевый ребенокот этогородительОтказ Мы устанавливаемродитель‘sЛевый ребеноккУзел‘sЛевый ребенок(единственный ребенок имеет).От линии 19 до линии 21: Мы охватываем - Узел только с одним
ребенок(Левый ребенок), и этоПравый ребенокот егородительОтказ Мы устанавливаемродитель‘sПравый ребеноккУзел‘sЛевый ребенок(единственный ребенок имеет).От линии 22 до линии 24: Мы охватываем - Узел только с одним
ребенок(Правильный ребенок), и этоЛевый ребенокот егородительОтказ Мы устанавливаемродитель‘sЛевый ребеноккУзел‘sПравый ребенок(единственный ребенок имеет).От линии 25 до линии 27: Мы охватываем - Узел только с одним
ребенок(Правильный ребенок), и этоПравый ребенокот егородительОтказ Мы устанавливаемродитель‘sПравый ребеноккУзел‘sПравый ребенок(единственный ребенок имеет).От линии 28 до линии 30: Мы охватываем - Узел с обоими
левыйиправильнодети. Мы получаемУзелС наименьшимценность(код показан ниже) и установить его наценностьизТекущий узелОтказ Закончить его, удалив самых маленькихУзелОтказЛиния 32: Если мы найдем - Узел Мы ищем, это необходимо вернуть
ПравдаОтказ От линии 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|
Тесты теперь сделаны.:)
Это все сейчас!
Мы многому научились здесь.
Поздравляю с заканчиванием этого плотного контента. Очень сложно понять концепцию, которую мы не знаем. Но ты сделал это.:)
Это еще один шаг вперед в моем путешествии к алгоритмам обучения и овладевания и структур данных. Вы можете увидеть документацию моего полного путешествия здесь на моем Ренессанс Разработчик Публикация Отказ
Веселитесь, продолжайте учиться и кодировать.
Дополнительные ресурсы
- Введение в структуру данных деревьев mycodeschool.
- Дерево Википедия
- Как не быть ошеломленным деревьями талантливыми Вааидехи Джоши
- Вступление на деревья, лекция профессором Джонатан Коэн
- Вступление на деревья, лекция профессором Дэвид Шмидт
- Вступление на деревья, лекция профессором Виктор Адамчик
- Деревья с Гейл Лаакманн Макдауэлл
- Реализация бинарных деревьев и Тесты По Тк.
- Курсера Курсера: структуры данных Университет Калифорнии, Сан-Диего
- Курсера курс: структуры данных и производительность Университет Калифорнии, Сан-Диего
- Концепции и реализация двоичных поисков и реализация Paul Programming
- Реализация двоичного поиска Дерево и Тесты По Тк.
- Треверс дерева Википедия
- Двоичное поиск дерева удалить алгоритм узла по GeeksForGeeks.
- Двоичное поиск деревьев Удалить алгоритм узла по Алголист
- Обучение питона от нуля до героя