二叉搜索树(Binary Search Tree)

二叉搜索树(Binary Search Tree,BST),又称为二叉搜索树,二叉排序树,是具有下列性质的二叉树:

  • 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  • 它的左、右子树也分别为二叉排序树。

基本方法有:

  1. 查找:递归查找是否存在key。
  2. 插入:原树中不存在key,插入key返回true,否则返回false。
  3. 构造:循环的插入操作。
  4. 删除:
    • 叶子节点:直接删除,不影响原树。
    • 仅有左子树或右子树的节点:节点删除后,将它的左子树或右子树整个移动到删除节点的位置就可以,子承父业。
    • 既有左子树又有右子树的节点:找到要删除节点p的直接前驱或者直接后继s,用s来替换节点p,然后再删除节点s。

二叉搜索树是一种经典的数据结构,既有链表的快速插入与删除操作的特点,又有数组快速查找的优势,所以应用广泛,例如,在文件系统和数据库系统一般会采用这种数据结构进行高效率的排序与检索操作。

Python 3实现

复制代码
# Python 3: binary search tree
class Node:
    def __init__(self, data):
        self.data = data
        self.lchild: Node = None
        self.rchild: Node = None


class BST:
    def __init__(self, root: Node = None):
        self.root = root

    def search(self, data):
        return self.__search(self.root, data)

    def __search(self, node: Node, data):
        if node is None:
            return None
        elif node.data == data:
            return node
        elif node.data > data:
            return self.__search(node.lchild, data)
        else:
            return self.__search(node.rchild, data)

    def insert(self, data):
        self.root = self.__insert(self.root, data)

    def __insert(self, node: Node, data):
        if node is None:
            node = Node(data)
        elif node.data == data:
            raise Exception(f'data[{data}] already exists!')
            # node = node
        elif node.data > data:
            node.lchild = self.__insert(node.lchild, data)
        else:
            node.rchild = self.__insert(node.rchild, data)
        return node

    def delete(self, data):
        self.__delete(self.root, data)

    def __delete(self, node: Node, data):
        if node is None:
            return
        elif node.data == data:
            if node.lchild is None and node.rchild is None:
                node = None
            elif node.lchild is None:
                node = node.rchild
            elif node.rchild is None:
                node = node.lchild
            else:  # node.lchild exists and node.rchild exists
                # find the minimum data in right child, or find the maximum data in left child.
                # here the minimum data in right child is used.
                temp = self.__min_value(node.rchild)
                node.data = temp.data
                # delete the duplicated node in right
                self.__delete(node.rchild, temp.data)
        elif node.data > data:
            node.lchild = self.__delete(node.lchild, data)
        else:
            node.rchild = self.__delete(node.rchild, data)
        return node

    def min_value(self):
        return self.__min_value(self.root)

    def __min_value(self, node: Node):
        if node.lchild is None:
            return node
        else:
            return self.__min_value(node.lchild)

    def max_value(self):
        return self.__max_value(self.root)

    def __max_value(self, node: Node):
        if node.rchild is None:
            return node
        else:
            return self.__max_value(node.rchild)

    def print(self):
        self.__print(self.root)

    def __print(self, node: Node):
        """
        in-order traverse
        :param node:
        """
        if node is None:
            return
        else:
            self.__print(node.lchild)
            print(node.data)
            self.__print(node.rchild)
复制代码

期望耗费

不论哪一种操作,所耗费的时间都和树的高度成正比。因此,如果共有n个元素,那么平均每次操作需要O(logn)的时间。

查找成功与不成功的概率:

有n个节点的二叉树的个数:Ω(4n/n3/2

图示

 

posted @   vicky2021  阅读(379)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示