二叉搜索树(展平、插入、查找、删除)

1. 按中序遍历的顺序展平二叉搜索树(先按中序遍历,将节点保存在列表中,再将列表中的节点连接成一个只有右子树的二叉树)

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def increasingBST(self, root: TreeNode) -> TreeNode:
        if not root:
            return []
        node_list=[]                   # 列表保存中序遍历的结果
        self.inorder(root,node_list)
        res=node_list[0]               # res为返回的二叉树根节点
        tail=res                       # tail指针指向表头
        tail.right=None                # 左右子树置为空
        tail.right=None
        lenth=len(node_list)
        for i in range(1,lenth):
            tail.right=node_list[i]
            tail=tail.right
            tail.left=None
            tail.right=None
        return res

    def inorder(self,root,node_list):   # 中序遍历
        if root:
            self.inorder(root.left,node_list)
            node_list.append(root)
            self.inorder(root.right,node_list)
        

2. 判断是否为二叉搜索树(二叉搜索树的中序遍历结果,是一个递增序列)

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def isValidBST(self , root: TreeNode) -> bool:
        # write code here
        # 二叉搜索树的中序遍历结果,是一个递增的序列
        if not root:
            return []
        BST_list=[]
        self.inorder(root,BST_list)   # 将中序遍历的结果保存在列表中
        lenth=len(BST_list)
        for i in range(0,lenth-1):    # 判断列表是不是个递增序列
            if BST_list[i]>=BST_list[i+1]:
                return False
        return True
    def inorder(self,root,BST_list):
        if root:
            self.inorder(root.left,BST_list)
            BST_list.append(root.val)
            self.inorder(root.right, BST_list)

3.二叉搜索树与双向链表 (二叉树的左右子树与双向链表的前后指针)

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def Convert(self , pRootOfTree ):
        # write code here
        if not pRootOfTree:
            return None
        node_list=[]
        self.inorder(pRootOfTree, node_list)   # 将中序遍历的结果保存在列表中
        Bihead=node_list[0]                    #双向链表的头结点
        Bihead.left=None                     
        Bihead.right=None
        tail=Bihead
        lenth=len(node_list)
        for i in range(1,lenth):
            node_list[i].right=None
            node_list[i].left=None
            tail.right=node_list[i]        # 二叉树的左子树和右子树代表双向链表的左指针和右指针
            tail.right.left=tail
            tail=tail.right
        return Bihead
    def inorder(self,root,node_list):
        if root:
            self.inorder(root.left, node_list)
            node_list.append(root)
            self.inorder(root.right, node_list)

4. 删除:

① 删除的节点为叶子节点:直接删除

② 删除的节点只有左子树或只有右子树:将其子树的根节点替换此节点

③ 删除的节点既有左子树又有右子树:用其右子树的最小节点代替,然后将代替的节点删除(这个代替的节点分为其为叶子节点和只有右子树两种情况)

# 节点的定义
class BiTreeNode:
    def __init__(self,data):
        self.data=data
        self.lchild=None
        self.rchild=None
        self.parent=None
# 二叉搜索树
class BST:
    def __init__(self):
        self.root=None
    # 插入
    def insert(self,node,val):
        if not node:
            node=BiTreeNode(val)
        elif val<node.data:  # 插入到左子树
            node.lchild=self.insert(node.lchild,val)
            node.lchild.parent=node
        elif val>node.data:   # 插入到右子树
            node.rchild=self.insert(node.rchild,val)
            node.rchild.parent=node
        return node
    # 查找
    def query(self,node,val):
        if not node:
            return None
        if node.data<val:
            return self.query(node.rchild,val)
        elif node.data>val:
            return self.query(node.lchild,val)
        else:
            return node
    # 删除
    # 1. 待删除节点为叶子节点
    def delete_leaf(self,node):
        if not node.parent:  # 当前节点也是根节点
            self.root=None
        if node==node.parent.lchild:  # 当前节点是其父节点的左孩子
            node.parent.lchild=None
        else:
            node.parent.rchild=None
    # 2.1 待删除节点只有左孩子
    def delete_onlyhave_lchild(self,node):
        if not node.parent:         # 当前节点是根节点
            self.root=node.lchild
            node.lchild.parent=None
        elif node==node.parent.lchild:  # 当前节点是其父节点的左孩子
            node.parent.lchild=node.lchild
            node.lchild.parent=node.parent
        else:                           #当前节点是其父节点的右孩子
            node.parent.rchild=node.lchild
            node.lchild.parent=node.parent
    # 2.2 待删除节点只有右孩子
    def delete_onlyhave_rchild(self,node):
        if not node.parent:
            self.root=node.rchild
            node.rchild.parent=None
        elif node==node.parent.lchild:
            node.parent.lchild=node.rchild
            node.rchild.parent=node.parent
        else:
            node.parent.rchild=node.rchild
            node.rchild.parent=node.parent
    def delete(self,val):
        if self.root:
            node=self.query(val)
            if not node:
                return None
            if node.lchild==None and node.rchild==None:  # 删除叶子节点
                self.delete_leaf(node)
            elif node.rchild==None:          # 只有左孩子
                self.delete_onlyhave_lchild(node)
            elif node.lchild==None:           # 只有右孩子
                self.delete_onlyhave_rchild()

            # 3. 待删除节点有两个子节点(将其右子树的最小节点替换该节点)
            else:
                # 先找右子树里最小的节点
                min_node=node.rchild
                while min_node.lchild:
                    min_node=min_node.lchild
                # 将要删除节点的值替换
                node.data=min_node.data
                # 删除替换的节点,替换的节点必定没有左孩子
                # 判断替换的节点是叶子节点还是只有一个右孩子
                if min_node.rchild:
                    self.delete_onlyhave_rchild(min_node)
                else:
                    self.delete_leaf(min_node)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值