python实现二叉搜索树

 笔记

python实现二叉搜索树

# -*- coding: UTF-8 -*-
'''
   *****************LLL*********************
   * @Project :leetcode                       
   * @File    :lll_110二叉搜索树.py                  
   * @IDE     :PyCharm             
   * @Author  :LLL                         
   * @Date    :2022/6/3 17:41             
   *****************************************
'''
from random import shuffle


# binary search tree
class BST:
    # 树节点
    class TreeNode:
        def __init__(self, val, lchild=None, rchild=None, parent=None):
            self.val = val
            self.lchild = lchild
            self.rchild = rchild
            self.parent = parent

    # 初始化根节点为空
    def __init__(self, li):
        self.root = None
        if li:
            for val in li:
                self.insert_no_rec(val)

    # 插入(递归写法) 从根节点开始,查找适合插入的位置
    def insert(self, root, val):
        if not root:
            root = self.TreeNode(val)
        elif val < root.val:
            root.lchild = self.insert(root.lchild, val)
            root.lchild.parent = root
        elif val > root.val:
            root.rchild = self.insert(root.rchild, val)
            root.rchild.parent = root
        else:
            pass
        return root

    # 插入(非递归写法)
    def insert_no_rec(self, val):
        tmp_node = self.root
        # 如果没有根节点
        if not tmp_node:
            self.root = self.TreeNode(val)
            return

        while tmp_node:
            if val < tmp_node.val:
                if not tmp_node.lchild:  # 为None说明已经到了叶子结点
                    tmp_node.lchild = self.TreeNode(val)
                    tmp_node.lchild.parent = tmp_node
                    return
                tmp_node = tmp_node.lchild
            elif val > tmp_node.val:
                if not tmp_node.rchild:
                    tmp_node.rchild = self.TreeNode(val)
                    tmp_node.rchild.parent = tmp_node
                    return
                tmp_node = tmp_node.rchild
            else:
                return

    # 查询(递归写法)
    def query(self, root, val):
        if not root: return  # 如果没有根 返回None
        if val < root.val:  # 小于 就在左子树上查找
            return self.query(root.lchild, val)
        if val > root.val:  # 大于 就在右子树上查找
            return self.query(root.rchild, val)
        else:  # 等于就直接返回当前节点
            return root

    # 查询(非递归写法)
    def query_no_rec(self, val):
        tmp_node = self.root
        if not tmp_node: return

        while tmp_node:
            if val < tmp_node.val:  # 小于就查找左子树
                tmp_node = tmp_node.lchild
            elif val > tmp_node.val:  # 大于就查找右子树
                tmp_node = tmp_node.rchild
            else:
                return tmp_node

    # 删除
    def delete(self, val):
        # 三种情况
        '''
        1.如果要删除的节点是叶子结点,直接删除
        2.如果要删除的节点只有一个孩子(不管是左孩子还是右孩子),将其孩子连向其父亲,然后删除该节点
        3.如果要删除的节点有两个孩子,寻找左子树的最大节点(或者右子树的最小节点)替换当前节点
        '''

        tmp_node = self.query_no_rec(val)
        if tmp_node:
            # 情况1
            if not tmp_node.lchild and not tmp_node.rchild:  # 如果是叶子节点
                if tmp_node.parent:
                    if tmp_node.parent.lchild == tmp_node:
                        tmp_node.parent.lchild = None
                    else:
                        tmp_node.parent.rchild = None
                else:  # 如果是根节点
                    self.root = None
            # 情况2
            elif tmp_node.lchild:
                tmp_node.parent.lchild = tmp_node.lchild
                tmp_node.lchild.parent = tmp_node.parent

            elif tmp_node.rchild:
                tmp_node.parent.rchild = tmp_node.rchild
                tmp_node.rchild.parent = tmp_node.parent

            # 情况3
            else:
                tmp_node2 = tmp_node.rchild  # 右子树
                while tmp_node2.lchild:  # 寻找右子树值最小的节点
                    tmp_node2 = tmp_node2.lchild

                tmp_node3 = tmp_node2.parent
                while tmp_node3.rchild:
                    tmp_node3 = tmp_node3.rchild

                tmp_node.val = tmp_node2.val
                tmp_node2.parent.lchild = None
                tmp_node3.rchild = tmp_node2.rchild
                tmp_node2.rchild.parent = tmp_node3
        else:
            print('要删除的节点不存在!')

    # 前序遍历
    def pre_order(self, root):
        if root:
            print(root.val, end=' ')
            self.in_order(root.lchild)
            self.in_order(root.rchild)

    # 中序遍历
    def in_order(self, root):
        if root:
            self.in_order(root.lchild)
            print(root.val, end=' ')
            self.in_order(root.rchild)

    # 后序遍历
    def post_order(self, root):
        if root:
            self.post_order(root.lchild)
            self.post_order(root.rchild)
            print(root.val, end=' ')


if __name__ == '__main__':
    li = list(range(1, 20))
    shuffle(li)
    bst = BST(li)
    print()
    # bst.pre_order(bst.root)
    print()
    bst.in_order(bst.root)
    bst.delete(1)
    # bst.delete(2)
    # bst.delete(16)
    # bst.delete(19)
    print()
    bst.in_order(bst.root)

同步更新于个人博客系统:python实现二叉搜索树 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值