Пост Написание двоичного поиска в Python – с примерами впервые появился на QVault Отказ
Двоичное дерево поиска или BST для коротких, это дерево, узлы которых каждый хранит ключ больше, чем все их левые дочерние узлы и меньше, чем все их правильные детские узлы. Двоичные деревья полезны для хранения данных организованным способом, что позволяет ему получать, вставленные, обновляться и быстро удалять. Чем больше и меньше, чем заказание узлов означает, что каждое сравнение пропускает около половины оставшегося дерева, поэтому весь этот образ занимает время пропорционально количеству узлов в дереве.
Быть точным, двоичные валы поиска обеспечивают среднюю сложность Big-O O (log (n))
Для поискового, вставки, обновления и удаления операций. Log (n) намного быстрее, чем линейный O (n)
Время, необходимое для поиска предметов в несортированном массиве. Многие популярные производственные базы данных, такие как PostgreSQL и MySQL, используют двоичные деревья под капотом для ускорения операций CRUD.
BST.
Шаг 1 – класс BSTNODE
Наша реализация не будет использовать Дерево
класс, но вместо этого просто Узел
класс. Двоичные деревья действительно просто указатель на корневом узле, который, в свою очередь, подключается к каждому узеру ребенка, поэтому мы будем работать с этой идеей.
Во-первых, мы создаем конструктор:
class BSTNode: def __init__ (self, val=None): self.left = None self.right = None self.val = val
Мы позволим предоставить значение (ключ), но если кто-то не предоставлен, мы просто настроим его на Нет
Отказ Мы также инициализируем обе дети нового узла для Нет
Отказ
Шаг 2 – Вставить
Нам нужен способ вставить новые данные. Метод вставки выглядит следующим образом:
def insert(self, val): if not self.val: self.val = val return if self.val == val: return if val < self.val: if self.left: self.left.insert(val) return self.left = BSTNode(val) return if self.right: self.right.insert(val) return self.right = BSTNode(val)
Если узел еще не имеет значения, мы можем просто установить заданное значение и возврат. Если мы когда-нибудь пытаемся вставить значение, которое также существует, мы также можем просто вернуться так, как это можно считать A NOOP
Отказ Если заданное значение меньше, чем значение нашего узла, и у нас уже есть левый ребенок, то мы рекурсивно звоните Вставить
на нашем левом ребенке. Если у нас нет левого ребенка, то мы просто сделаем данную ценность нашим новым левым ребенком. Мы можем сделать то же самое (но перевернутое) для нашей правой стороны.
Шаг 3 – Получите мин и получите максимум
def get_min(self): current = self while current.left is not None: current = current.left return current.val def get_max(self): current = self while current.right is not None: current = current.right return current.val
Getmin
и getmax
Полезные функции помощника, и их легко писать! Они являются простыми рекурсивными функциями, которые проходят по краям дерева, чтобы найти самые маленькие или самые большие значения, хранящиеся в нем.
Шаг 4 – Удалить
def delete(self, val): if self == None: return self if val < self.val: self.left = self.left.delete(val) return self if val > self.val: self.right = self.right.delete(val) return self if self.right == None: return self.left if self.left == None: return self.right min_larger_node = self.right while min_larger_node.left: min_larger_node = min_larger_node.left self.val = min_larger_node.val self.right = self.right.delete(min_larger_node.val) return selfdef delete(self, val): if self == None: return self if val < self.val: if self.left: self.left = self.left.delete(val) return self if val > self.val: if self.right: self.right = self.right.delete(val) return self if self.right == None: return self.left if self.left == None: return self.right min_larger_node = self.right while min_larger_node.left: min_larger_node = min_larger_node.left self.val = min_larger_node.val self.right = self.right.delete(min_larger_node.val) return selfdef delete(self, val): if self == None: return self if val < self.val: self.left = self.left.delete(val) return self if val > self.val: self.right = self.right.delete(val) return self if self.right == None: return self.left if self.left == None: return self.right min_larger_node = self.right while min_larger_node.left: min_larger_node = min_larger_node.left self.val = min_larger_node.val self.right = self.right.delete(min_larger_node.val) return self
Операция удаления является одним из более сложных. Это также рекурсивная функция, но также возвращает новое состояние данного узла после выполнения операции удаления. Это позволяет родителю, чей ребенок был удален, чтобы правильно установить это левый
или правильно
Участник данных на Нет
Отказ
Шаг 5 – Существуют
Функция существующая функция – еще одна простая рекурсивная функция, которая возвращает Правда
или Ложь
В зависимости от того, существует ли данное значение в дереве.
def exists(self, val): if val == self.val: return True if val < self.val: if self.left == None: return False return self.left.exists(val) if self.right == None: return False return self.right.exists(val)
Шаг 6 – Interorder
Это полезно иметь возможность распечатать дерево в читаемом формате. Inordorder
Метод Печать значения в дереве в порядке их клавиш.
def inorder(self, vals): if self.left is not None: self.left.inorder(vals) if self.val is not None: vals.append(self.val) if self.right is not None: self.right.inorder(vals) return vals
Шаг 7 – Предоставляет
def preorder(self, vals): if self.val is not None: vals.append(self.val) if self.left is not None: self.left.preorder(vals) if self.right is not None: self.right.preorder(vals) return vals
Шаг 8 – Сообщение
def postorder(self, vals): if self.left is not None: self.left.postorder(vals) if self.right is not None: self.right.postorder(vals) if self.val is not None: vals.append(self.val) return vals
использование
def main(): nums = [12, 6, 18, 19, 21, 11, 3, 5, 4, 24, 18] bst = BSTNode() for num in nums: bst.insert(num) print("preorder:") print(bst.preorder([])) print("#") print("postorder:") print(bst.postorder([])) print("#") print("inorder:") print(bst.inorder([])) print("#") nums = [2, 6, 20] print("deleting " + str(nums)) for num in nums: bst.delete(num) print("#") print("4 exists:") print(bst.exists(4)) print("2 exists:") print(bst.exists(2)) print("12 exists:") print(bst.exists(12)) print("18 exists:") print(bst.exists(18))
Полное двоичное дерево поиска в Python
class BSTNode: def __init__ (self, val=None): self.left = None self.right = None self.val = val def insert(self, val): if not self.val: self.val = val return if self.val == val: return if val < self.val: if self.left: self.left.insert(val) return self.left = BSTNode(val) return if self.right: self.right.insert(val) return self.right = BSTNode(val) def get_min(self): current = self while current.left is not None: current = current.left return current.val def get_max(self): current = self while current.right is not None: current = current.right return current.val def delete(self, val): if self == None: return self if val < self.val: if self.left: self.left = self.left.delete(val) return self if val > self.val: if self.right: self.right = self.right.delete(val) return self if self.right == None: return self.left if self.left == None: return self.right min_larger_node = self.right while min_larger_node.left: min_larger_node = min_larger_node.left self.val = min_larger_node.val self.right = self.right.delete(min_larger_node.val) return self def exists(self, val): if val == self.val: return True if val < self.val: if self.left == None: return False return self.left.exists(val) if self.right == None: return False return self.right.exists(val) def preorder(self, vals): if self.val is not None: vals.append(self.val) if self.left is not None: self.left.preorder(vals) if self.right is not None: self.right.preorder(vals) return vals def inorder(self, vals): if self.left is not None: self.left.inorder(vals) if self.val is not None: vals.append(self.val) if self.right is not None: self.right.inorder(vals) return vals def postorder(self, vals): if self.left is not None: self.left.postorder(vals) if self.right is not None: self.right.postorder(vals) if self.val is not None: vals.append(self.val) return vals
Спасибо за чтение!
Возьми Курсы компьютерных наук на нашей новой платформе
Следуйте и ударим нас в Twitter @q_vault. Если у вас есть какие-либо вопросы или Комментарии
Подписаться на нашу рассылку для большего количества стран программирования
Связанное чтение
Оригинал: “https://dev.to/qvault/writing-a-binary-search-tree-in-python-with-examples-2dbe”