二叉搜索树

一、 二叉搜索树定义:
二叉搜索树是一种特殊的二叉树,满足以下两个特点:
1 每个节点处的值大于等于其左子树上的值
2 每个节点处的值小于等于其右子树上的值
示例:
在这里插入图片描述
中序遍历二叉搜索树树可以得到这些值的升序排序。
判断二叉树是否为二叉搜索树:
1 用递归的思想判断每个节点是否满足定义的两个特点
2 中序遍历二叉树,看是否为升序
方法一:

def ValidBST(root, minv, maxv):
	if root == None:
		return True
	if (root.val < minv or root.val > maxv):
		return False
	left_result = self.ValidBST(root.left, minv, root.val)
	right_result = self.ValidBST(root.right, root.val, maxv)
	return left_result and right_result
def isValidBST(self, root):
	maxv = Inf
	minv = -Inf
	return self.ValidBST(root, minv, maxv)

方法二:

def inorderTraverse(self, root):
	if root == None:
		return [ ]
	res = [ ]
	res += self.inorderTraverse(root.left)
	res.append(root.val)
	res += self.inorderTraverse(root.right)
	return res

def isValidBST(self, root):
	res = self.inorderTraverse(root)
	if( res != sorted(list(set(res))):
		return False
	return True

二、二叉搜索树的常见操作
二叉搜索树常见的操作有查找,插入和删除

1 查找操作

  • 比较当前节点值和要查找的key是否相同, 若相同则找到,返回节点。
  • 若key 小于当前节点值,则查找其左子树
  • 若key大于当前节点值,则查找右子树
def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if(root == None):
            return []
        if(root.val == val):
            return root
        elif(val < root.val):
            return self.searchBST(root.left, val)
        else :
            return self.searchBST(root.right, val)
        

2 插入操作
给定二叉搜索树,插入一个值,有多种方式实现。这里给出改动最小的一种方式。

  1. 根据目标value和当前节点值的关系,去查找其左子树或者右子树
  2. 重复步骤一直到找到一个外部节点
  3. 根据目标value和外部节点值之间的关系,将目标value查到外部节点的左子树或者右子树。
def insertBST(self, root, val):
	if(root == None):
		root = TreeNode(val)
		return root
	if (val < root.val):
		left = root.left
		if(left == None):
			left = TreeNode(val)
		else :
			left = self.insertBST(left, val)
	elif (val > root.val):
		right = root.right
		if(right == None):
			right = TreeNode(val)
		else :
			right = self.insertBST(right, val)
	root.left = left
	root.right = right
	return root
			

3 删除操作
删除操作要比查找和插入操作更为复杂。和插入操作类似,也有多种删除策略,这里我们介绍改动最小的那种。主要思路是替换目标value和其合适的child,然后删除child。

  1. If the target node has no child, we can simply remove the node.
  2. If the target node has one child, we can use its child to replace itself.
  3. If the target node has two children, replace the node with its in-order successor or predecessor node and delete that node.

图解示例:
在这里插入图片描述
整体思路:
1 找到替换Node, 替换
2 删除操作。
方法一: 和前驱换

 def deleteNode(self, root, key):
            if(root == None):
                return None
            if(root.val == key):
                if not root.left:
                    right = root.right
                    return right
                else:
                    left = root.left
                    while left.right:
                        left = left.right
                    root.val, left.val = left.val , root.val
            root.left = self.deleteNode(root.left, key)
            root.right = self.deleteNode(root.right, key)
            return root

方法二: 和后继换

def deleteNode(self, root, val):
	if (root == None):
		return None
	if (root.val == val):
		if not root.right :
			left = root.left
			return left
		else :
			right = root.right
			while right.left:
				right = right.left
			root.val , right.val = right.val, root.val
	root.left = self.deleteNode(root.left, val)
	root.right = self.deleteNode(root.right, val)
	return root
			

三、 总结
** 二叉搜索树的优势是, 所有操作(查找、插入、删除)都可以在o(h)时间复杂度内完成。通常, 如果需要按序存储一些数据,并且需要同时执行多个操作(查找、插入、删除),那么BST是一个不错的选择。**

应用:
查找数据流中第k大的数字
在这里插入图片描述
解题方法:小根堆
Python的堆是小根堆,不需要对其进行转换,我们想一想,如果一个堆的大小是k的话,那么最小的数字就在其最前面(即为第k大的数字),只要维护当新来的数字和最前面的这个数字比较即可。

所以我们的工作就是维护一个小根堆,这个小根堆保存的是从第K大的数字到最大的数字。堆的大小即为K。

class KthLargest:

    def __init__(self, k: int, nums: List[int]):
        self.k = k
        self.pool = nums
        self.size = len(self.pool)
        heapq.heapify(self.pool)
        while self.size > self.k:
            heapq.heappop(self.pool)
            self.size = self.size -1

    def add(self, val: int) -> int:
        if(self.size < self.k):
            heapq.heappush(self.pool, val)
            self.size += 1
        elif (val > self.pool[0]):
            heapq.heapreplace(self.pool, val)
        return self.pool[0]


# Your KthLargest object will be instantiated and called as such:
# obj = KthLargest(k, nums)
# param_1 = obj.add(val)

Lowest Common Ancestor of a Binary Search Tree
Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5]

在这里插入图片描述

class Solution:
    
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        maxval = max(p.val, q.val)
        minval = min(p.val, q.val)
        if root == None:
            return None
        elif(maxval > root.val and minval < root.val):
            return root
        elif (root.val == maxval or root.val == minval):
            return root
        elif (maxval < root.val):
            return self.lowestCommonAncestor(root.left, p, q)
        elif (minval > root.val):
            return self.lowestCommonAncestor(root.right, p, q)
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值