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

Написание двоичного дерева поиска в Python – с примерами

Пост написание бинарного поиска дерева в Python – с примерами впервые появились на QVault. Бинарный … Теги с Python, компьютерные науки, языки, списком рассылки.

Пост Написание двоичного поиска в 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”