第二章:二叉搜索树操作集锦

本文深入解析二叉树及二叉搜索树的多种算法,包括遍历、搜索、插入、删除等核心操作,通过递归框架简化问题解决,同时探讨不同遍历方式的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

labuladong 二叉搜索树操作集锦

  • 二叉树
    • 二叉树算法设计的总路线:把当前节点要做的事做好,其他的交给递归框架,不用当前节点操心。 (可以理解成递归方法的应用)
      • 明确递归结束的条件 (已经到了叶子节点)
      • 把root该做的事情做完, 然后左右子节点递归调用该方法
    • 如果当前节点会对下面的子节点有整体影响,可以通过辅助函数增长参数列表,借助参数传递信息。
void traverse(TreeNode root) {
    // root 需要做什么?在这做。
    // 其他的不用 root 操心,抛给框架
    traverse(root.left);
    traverse(root.right);
}
  • 二叉搜索树
    • 定义:任意节点的值要大于等于左子树所有节点的值,且要小于等于右子树的所有节点的值。
    • 因此,中序遍历二叉搜索树后,可以得到递增数组。
void BST(TreeNode root, int target) {
    if (root.val == target)
        // 找到目标,做点什么
    if (root.val < target) 
        BST(root.right, target);
    if (root.val > target)
        BST(root.left, target);
}

100. 相同的树

  • 函数内先判断两个root节点是否相等,然后递归调用该函数,判断左右子节点是否相等
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSameTree(self, p, q):
        """
        :type p: TreeNode
        :type q: TreeNode
        :rtype: bool
        """
        if p==None and q ==None: return True # 都为空节点
        if p==None or q ==None: return False # 其中一个为空节点
        if p.val!=q.val:return False # 值不相等
        # 调用递归,判断左右子树是否都满足isSameTree
        return self.isSameTree(p.left,q.left) and self.isSameTree(p.right,q.right)

面试题 04.05. 合法二叉搜索树

方法1:利用携带的最大最小值进行判断

  • root 需要做的不只是和左右子节点比较,而是要和整个左子树和右子树所有节点比较

  • 使用辅助函数,增加函数参数列表,在参数中携带额外信息(当前节点需要比较的最小值和最大值)

    • 直接赋予最小值-float("inf")、最大值float("inf"),在递归的过程中修改最值(自顶向下的过程中,右子树的最小值从-float("inf") 逐渐增大,左子树的最大值从float("inf") 逐渐减小

以该不合法的二叉搜索树树为例:

  • 遍历到15 时,15与 [10, float("inf")] 比较,结果是True(此时最小值为10)
  • 对于15的左子树,它应该在[10,15] 范围内,但现在是6,结果为False
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        def valid(root,mi,ma):
            if root==None: return True
            if root.val<=mi: return False
            if root.val>=ma: return False
            return valid(root.left, mi , root.val) and valid(root.right, root.val, ma)
        return valid(root, -float("inf"), float("inf"))

方法2:中序遍历二叉搜索树后,判断其是否为没有重复元素的递增数组

  • 最后的return nodes == sorted(set(nodes)), 要先set,再 sorted,这样返回的是列表形式,即判断列表是否等于列表(若先sorted,再set,返回的是一个集合,即判断列表是否等于集合,出现错误)
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def isValidBST(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        nodes=[]
        def inOrder(root): # 中序遍历后,判断其是否递增
            if not root: return True
            inOrder(root.left)
            nodes.append(root.val)
            inOrder(root.right)
            return nodes
        
        inOrder(root)
        return nodes == sorted(set(nodes))

700. 二叉搜索树中的搜索

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if not root: return None
        if root.val==val: return root
        if root.val>val:
            return seatchBST(self,root.left,val)
        if root.val<val:
            return searchBST(self,root.right,val)

701.二叉搜索树的插入操作

对数据结构的操作无非遍历 + 访问,遍历就是“找”,访问就是“改”。具体到这个问题,插入一个数,就是先找到插入位置,然后进行插入操作。

上一个问题,我们总结了 BST 中的遍历框架,就是“找”的问题。直接套框架,加上“改”的操作即可。一旦涉及“”,函数就要返回 TreeNode 类型,并且对递归调用的返回值进行接收。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def insertIntoBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if not root:
            root=TreeNode(val)
            return root
        if val>root.val:
            root.right=self.insertIntoBST(root.right,val)
        elif val< root.val:
            root.left=self.insertIntoBST(root.left,val)
        return root

450. 删除二叉搜索树中的节点

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def deleteNode(self, root, key):
        """
        :type root: TreeNode
        :type key: int
        :rtype: TreeNode
        """


        # 若无根节点,直接返回
        if not root:return None
        # 若找到目标值
        if root.val==key:
        	# 处理无子节点/只有一个子节点的情况
            if root.left==None: return root.right
            if root.right==None: return root.left

            # 找到右子树的最左(小)节点,并替换
            minNode=self.getMin(root.right)
            root.val=minNode.val
            # 转而删除最小节点
            root.right=self.deleteNode(root.right,minNode.val)
        # 二叉搜索树
        elif root.val>key:
            root.left=self.deleteNode(root.left,key)
        else:
            root.right=self.deleteNode(root.right,key)
        return root

    def getMin(self,root): # 最小值一定在左叶子节点处
        while root.left!=None:
            root=root.left
        return root

二叉树的遍历

前序、中序、后序、层序遍历 打包,讲解很棒!

只需要改变遍历的顺序即可
前序遍历

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        def helper(root):
            if not root:return 
            res.append(root.val)
            helper(root.left)
            helper(root.right)
        helper(root)
        return res

中序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def inorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res=[]
        def helper(root):
            if not root: return 
            helper(root.left)
            res.append(root.val)
            helper(root.right)
        helper(root)
        return res

后序遍历

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        res = []
        def helper(root):
            if not root:
                return 
            helper(root.left)
            helper(root.right)
            res.append(root.val)
        helper(root)
        return res

层序遍历

  • 队列中存储当前层的节点,然后利用先进先出特性将结果保存

剑指 Offer 32 - I. 从上到下打印二叉树

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        if not root: return []
        from collections import deque
        res=[]
        queue=deque()
        queue.append(root)
        while queue:
            node=queue.popleft()
            res.append(node.val)
            if node.left:queue.append(node.left)
            if node.right:queue.append(node.right)
        return res

102. 二叉树的层序遍历

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def levelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        if not root: return []
        res = []
        queue = collections.deque()
        queue.append(root)
        while queue:
            tmp = []
            for i in range(len(queue)):         
                node = queue.popleft()
                tmp.append(node.val)
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
            res.append(tmp)
        return res

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值