二叉排序树(BST)

二叉排序树

基本介绍

二叉排序树创建和遍历

python 复制代码
class Node:
    """
    创建 Node 节点
    """
    value: int = 0
    left = None
    right = None

    def __init__(self, value: int):
        self.value = value

    def add(self, node):
        """
        添加节点
        node 表示要添加的节点
        """
        if node is None:
            return
        # 判断要添加节点和当前子树根节点的大小
        if node.value < self.value:
            # 要添加节点小于当前子树根节点
            if self.left is None:
                # 如果当前子树左子节点为空,则直接将要添加的节点挂在左子节点上
                self.left = node
            else:
                # 否则,递归当前子树的左节点,找到要放置的位置
                self.left.add(node)
        else:  # 要添加节点大于等于当前子树根节点
            if self.right is None:
                # 如果当前子树右子节点为空,则直接将要添加的节点挂在右子节点上
                self.right = node
            else:
                # 否则,递归当前子树的右节点,找到要放置的位置
                self.right.add(node)

    def infix_order(self):
        """
        中序遍历二叉树
        """
        if self.left:
            self.left.infix_order()
        print(self.value)
        if self.right:
            self.right.infix_order()


class BinarySortTree:
    """
    二叉排序树
    """
    root: Node = None

    def add(self, node: Node):
        """
        添加节点
        node: 要添加的节点
        """
        if self.root is None:
            # 如果根节点为空,直接将新节点当做根节点
            self.root = node
        else:
            # 否则,将新节点放在根节点下
            self.root.add(node)

    def infix_order(self):
        """
        中序遍历
        """
        if self.root:
            self.root.infix_order()
        else:
            print("二叉排序树为空...")


arr = [7, 3, 10, 12, 5, 1, 9]
binary_sort_tree = BinarySortTree()
for i in arr:
    node = Node(i)
    binary_sort_tree.add(node)
binary_sort_tree.infix_order()

二叉排序树的节点删除

思路分析

代码实现

python 复制代码
"""二叉排序树"""
class Node:
    """
    创建 Node 节点
    """
    value: int = 0
    left = None
    right = None

    def __init__(self, value: int):
        self.value = value



    def add(self, node):
        """
        添加节点
        node 表示要添加的节点
        """
        if node is None:
            return
        # 判断要添加节点和当前子树根节点的大小
        if node.value < self.value:
            # 要添加节点小于当前子树根节点
            if self.left is None:
                # 如果当前子树左子节点为空,则直接将要添加的节点挂在左子节点上
                self.left = node
            else:
                # 否则,递归当前子树的左节点,找到要放置的位置
                self.left.add(node)
        else:  # 要添加节点大于等于当前子树根节点
            if self.right is None:
                # 如果当前子树右子节点为空,则直接将要添加的节点挂在右子节点上
                self.right = node
            else:
                # 否则,递归当前子树的右节点,找到要放置的位置
                self.right.add(node)

    def infix_order(self):
        """
        中序遍历二叉树
        """
        if self.left:
            self.left.infix_order()
        print(self.value)
        if self.right:
            self.right.infix_order()

    def search_delete(self, value: int):
        """
        查找要删除的节点
        :param value: 要删除节点的值
        :return:
        """
        if self.value == value:  # 当前节点就是要找的删除的节点,返回
            return self
        elif value < self.value:  # 要删除的值小于当前节点的值,则在当前节点的左子树递归查找
            if self.left:
                return self.left.search_delete(value)
            return None
        else:  # 要删除的值大于当前节点的值,则在当前节点的右子树递归查找
            if self.right:
                return self.right.search_delete(value)
            return None

    def find_parent(self, value: int):
        """
        查找要删除节点的父节点
        :param value: 要删除的节点值
        :return:
        """
        if (self.left and self.left.value == value or
                self.right and self.right.value == value):
            return self
        else:
            # 如果要删除的值小于当前节点的值,且当前节点有左节点,则向左节点递归查找
            if value < self.value and self.left:
                return self.left.find_parent(value)
            # 如果要删除的值大于等于当前节点的值,且当前节点有右节点,则向右 节点递归查找
            elif value >= self.value and self.right:
                return self.right.find_parent(value)
            return None  # 没有找到父节点,返回空,表示没有父节点,即要删除的是根节点


class BinarySortTree:
    """
    二叉排序树
    """
    root: Node = None

    def add(self, node: Node):
        """
        添加节点
        node: 要添加的节点
        """
        if self.root is None:
            # 如果根节点为空,直接将新节点当做根节点
            self.root = node
        else:
            # 否则,将新节点放在根节点下
            self.root.add(node)

    def infix_order(self):
        """
        中序遍历
        """
        if self.root:
            self.root.infix_order()
        else:
            print("二叉排序树为空...")

    def search_delete(self, value) -> Node:
        """
        查找要删除的节点
        :param value: 要删除节点的值
        :return:
        """
        if self.root:
            return self.root.search_delete(value)
        return None

    def find_parent(self, value) -> Node:
        """
        查找要删除节点的父节点
        :param value: 要删除节点的值
        :return:
        """
        if self.root:
            return self.root.find_parent(value)
        return None

    def find_and_delete_right_tree_min(self, node: Node) -> int:
        """
        查找以 node 为根节点的二叉排序树的最小节点
        返回小节点的值并从该二叉排序树中删除最小节点
        :param node:
        :return:
        """
        t = node
        while t.left:  # 因为要找最小节点,所以从二叉排序树的左子树中找
            t = t.left
        # 退出循环时,t 指向的就是最小节点
        val = t.value
        self.delete_node(val)
        return val

    def delete_node(self, value: int):
        """
        删除接地那
        :param value: 要删除节点的值
        :return:
        """
        if self.root is None:
            print("二叉树为空,不能删除节点...")
            return
        # 查找要删除的节点
        target_node = self.search_delete(value)
        if target_node is None:  # 找不到要删除的节点
            print(f"节点{value}不存在")
            return
        if self.root.left is None and self.root.right is None:
            # 此时找到了要删除的节点,且二叉树只有一个节点,所以要删除的就是这唯一的一个节点
            self.root = None
            return
        # 查找要删除节点的父节点
        parent = self.find_parent(value)
        if target_node.left is None and target_node.right is None:
            # 此时说明要删除的节点是叶子节点
            # 进一步判断要删除的节点是父节点的左节点还是右节点
            if parent.left and parent.left.value == value:
                # 说明要删除节点是父节点的左子节点
                parent.left = None
                return
            if parent.right and parent.right.value == value:
                # 说明要删除节点是父节点的右子节点
                parent.right = None
                return
        elif target_node.left and target_node.right:
            # 要删除的节点有左右两棵子树
            # 从要删除节点的右子树中找到最小节点,获得该最小节点的值并删除该最小节点
            # 然后将最小节点的值赋值给要删除节点
            min_val = self.find_and_delete_right_tree_min(target_node.right)
            target_node.value = min_val

            # 同理,也可以从要删除节点的左子树找到最大节点,获得该最大节点的值并删除该最大节点
            # 然后将最大节点的值赋值给要删除节点
        else:
            # 要删除的节点只有一棵子树
            # 进一步确定要删除节点的子树是左子树还是右子树
            if target_node.left:
                # 要删除节点的子树是左子树
                if parent is None:
                    # 如果父节点为空,说明要删除的是根节点,则直接让根基诶到哪等于它的左子节点
                    self.root = target_node.left
                # 进一步判断要删除的节点是父节点的左节点还是右节点
                elif parent.left.value == value:
                    # 要删除的节点是父节点的左节点
                    parent.left = target_node.left
                else:  # 要删除的节点是父节点的右节点
                    parent.right = target_node.left
            else:  # 要删除节点的子树是右子树
                if parent is None:
                    # 如果父节点为空,说明要删除的是根节点,则直接让根基诶到哪等于它的右子节点
                    self.root = target_node.right
                # 进一步判断要删除的节点是父节点的左节点还是右节点
                elif parent.left.value == value:
                    # 要删除的节点是父节点的左节点
                    parent.left = target_node.right
                else:  # 要删除的节点是父节点的右节点
                    parent.right = target_node.right


# 测试二叉排序树的创建和遍历
arr = [7, 3, 10, 12, 5, 1, 9, 2]
binary_sort_tree = BinarySortTree()
for i in arr:
    node = Node(i)
    binary_sort_tree.add(node)
binary_sort_tree.infix_order()
# 测试删除二叉排序树的结点
binary_sort_tree.delete_node(7)
print("删除节点后:")
binary_sort_tree.infix_order()
相关推荐
The_Ticker3 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
傻啦嘿哟21 分钟前
如何使用 Python 开发一个简单的文本数据转换为 Excel 工具
开发语言·python·excel
B站计算机毕业设计超人28 分钟前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
Lenyiin36 分钟前
02.06、回文链表
数据结构·leetcode·链表
爪哇学长39 分钟前
双指针算法详解:原理、应用场景及代码示例
java·数据结构·算法
爱摸鱼的孔乙己41 分钟前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan43 分钟前
C语言:数组转换指针的时机
c语言·开发语言·算法
IT古董1 小时前
【人工智能】Python在机器学习与人工智能中的应用
开发语言·人工智能·python·机器学习
繁依Fanyi1 小时前
简易安卓句分器实现
java·服务器·开发语言·算法·eclipse
烦躁的大鼻嘎1 小时前
模拟算法实例讲解:从理论到实践的编程之旅
数据结构·c++·算法·leetcode