📜  alberi binari di ricerca python (1)

📅  最后修改于: 2023-12-03 15:29:19.066000             🧑  作者: Mango

Python中的二叉搜索树(Binary Search Tree)

什么是二叉搜索树

二叉搜索树是一种特殊的二叉树,其中每个节点都包含一个键值,并满足以下条件:

  1. 左子树中的所有键值都小于根节点的键值;
  2. 右子树中的所有键值都大于根节点的键值;
  3. 左子树和右子树都是二叉搜索树。

这种结构可以很方便地实现对键值的查找、插入和删除操作。

用Python实现二叉搜索树
定义Node类

我们首先要定义一个Node类,这个类代表树中的节点。每个节点包含两个指针,用于指向左右子节点,以及一个键值。

class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.key = key
定义BST类

接下来,我们定义一个BinarySearchTree(BST)类,这个类代表整个二叉搜索树。BST类包含一个指针root,用于指向根节点。

class BinarySearchTree:
    def __init__(self):
        self.root = None
插入节点

插入节点涉及到递归操作。我们从根节点开始遍历树,在插入新节点时,如果新节点的键值小于当前节点的键值,则向左子树递归;否则向右子树递归。如果递归到叶节点处,说明新节点应该插入在这个位置。

def insert(self, key):
    if self.root is None:
        self.root = Node(key)
    else:
        self._insert(key, self.root)

def _insert(self, key, node):
    if key < node.key:
        if node.left is None:
            node.left = Node(key)
        else:
            self._insert(key, node.left)
    elif key > node.key:
        if node.right is None:
            node.right = Node(key)
        else:
            self._insert(key, node.right)
查找节点

查找节点也是递归进行的。我们从根节点开始遍历树,在查找节点时,如果节点的键值小于当前节点的键值,则向左子树递归;否则向右子树递归。如果找到节点,返回True,如果递归到叶节点但未找到节点,返回False。

def search(self, key):
    return self._search(key, self.root)

def _search(self, key, node):
    if node is None:
        return False
    elif key == node.key:
        return True
    elif key < node.key:
        return self._search(key, node.left)
    else:
        return self._search(key, node.right)
删除节点

删除节点比较复杂,因为我们需要考虑多种情况。首先需要找到待删除节点,分为以下三种情况:

  1. 待删除节点为叶节点(即没有子节点)。
  2. 待删除节点有一个子节点。
  3. 待删除节点有两个子节点。

对于情况1,我们只需要直接删除该节点。对于情况2,我们需要将该节点的子节点连接到该节点的父节点上。对于情况3,我们需要找到该节点右子树中最小的节点,用它来替换这个节点,并将该节点从右子树中删除。

def delete(self, key):
    self.root = self._delete(key, self.root)

def _delete(self, key, node):
    if node is None:
        return node
    elif key < node.key:
        node.left = self._delete(key, node.left)
        return node
    elif key > node.key:
        node.right = self._delete(key, node.right)
        return node
    else:
        if node.left is None and node.right is None:
            node = None
            return node
        elif node.left is None:
            node = node.right
            return node
        elif node.right is None:
            node = node.left
            return node
        else:
            min_node = self._find_min(node.right)
            node.key = min_node.key
            node.right = self._delete(min_node.key, node.right)
            return node

def _find_min(self, node):
    while node.left is not None:
        node = node.left
    return node
示例代码
class Node:
    def __init__(self, key):
        self.left = None
        self.right = None
        self.key = key

class BinarySearchTree:
    def __init__(self):
        self.root = None

    def insert(self, key):
        if self.root is None:
            self.root = Node(key)
        else:
            self._insert(key, self.root)

    def _insert(self, key, node):
        if key < node.key:
            if node.left is None:
                node.left = Node(key)
            else:
                self._insert(key, node.left)
        elif key > node.key:
            if node.right is None:
                node.right = Node(key)
            else:
                self._insert(key, node.right)

    def search(self, key):
        return self._search(key, self.root)

    def _search(self, key, node):
        if node is None:
            return False
        elif key == node.key:
            return True
        elif key < node.key:
            return self._search(key, node.left)
        else:
            return self._search(key, node.right)

    def delete(self, key):
        self.root = self._delete(key, self.root)

    def _delete(self, key, node):
        if node is None:
            return node
        elif key < node.key:
            node.left = self._delete(key, node.left)
            return node
        elif key > node.key:
            node.right = self._delete(key, node.right)
            return node
        else:
            if node.left is None and node.right is None:
                node = None
                return node
            elif node.left is None:
                node = node.right
                return node
            elif node.right is None:
                node = node.left
                return node
            else:
                min_node = self._find_min(node.right)
                node.key = min_node.key
                node.right = self._delete(min_node.key, node.right)
                return node

    def _find_min(self, node):
        while node.left is not None:
            node = node.left
        return node
总结

二叉搜索树是一种基本的数据结构,可以很方便地实现数据的查找、插入和删除。在Python中,我们可以使用递归来实现这些操作。在实际应用中,需要注意避免二叉搜索树退化为单向链表的情况,这样会导致操作的时间复杂度变为O(n)。