二叉搜索树的最近公共祖先
这个题和二叉树的最近公共祖先很像,你也可像二叉树那样去做,但是就是没有用到二叉树的性质
二叉树的性质可以用来完成剪枝的操作。
二叉树搜索树就是,你可以找左边和找右边,根据p,q的value的大小
如果 p,q 都小于key的value, 那么就走root.left 都大于,走root.right。否则,就改返回了 此时的root就是该节点。
递归
def dfs(root, p, q):
if not root: return None
if root.val > p.val and root.val > q.val:
left = dfs(root.left, p, q)
if left is not None:
return left
if root.val < p.val and root.val < q.val:
right = dfs(root.right, p, q)
if right is not None:
return right
return root
迭代法,这个题也可以用迭代,因为有序数组。
思路一样
def lowestCommonAncestor(root, p, q):
while (root):
if (root.val > p.val and root.val > q.val):
root = root.left
elif(root.val < p.val and root.val < q.val):
root = root.right
else:
reutrn root
return None
二叉搜索树的插入
其实这个题很简单,你模拟就知道,你插入的节点必然是叶子节点,对叶子节点进行操作。
这个题可以递归和迭代的思路,因为二叉搜索树是有序的。
我们先用迭代的思路,这个很好理解
当root.val > val root = root.left
root.val < val root = root.right
什么时候停止呢? 因为这个插入的节点是不相等的。一个简单的想法就是while cur is not None.
但是当他走到叶子节点的时候,他还会继续往下走,cur.left 就是None。那其实我们需要保存一个cur节点用一个变量parent,让parent去操作!
迭代法
def insertBST(root, key):
node = TreeNode(key)
if not root:
return node
cur = root
parent = root
while cur:
parent = cur
if cur.val > key:
cur = cur.left
else:
cur = cur.right
if parent.cur > key:
parent.left = node
else:
parent.right = node
return root
递归法
class Solution:
def dfs(self, root, val):
if (root == None):
node = TreeNode(val)
return node
if (root.val > val) root.left = self.dfs(root.left, val)
if (root.val < val) root.right = self.dfs(root.right, val)
return root
二叉搜索树的删除
二叉搜索树的删除要考虑很多情况
同样递归三部曲
1. 递归函数的参数和返回值:参数就是root 和key
2. 中止条件:如果遇到是空 就返回root
3. 确认单层递归,分情况讨论
1. 没找到删除删除的节点,遇到空节点就直接返回了
2.找到删除的节点
1. 如果是叶子节点,那么直接删除节点,返回null为根节点
2. 删除节点左孩子不为空,右孩子为空,删除该节点,右孩子补位
3. 删除节点左孩子为空,右孩子不为空,删除该节点,左孩子补位
4. 删除节点左右孩子都不为空。那么就要找到右子树最左边的叶子节点,然后将该头节点的左子树凭借到删除节点右子树的最左边的孩子上。如下图所示【图片来源于代码随想录】
假设要删除的元素是7
将7的左子树放在7的右子树左边的节点
将7节点删除,右子树为新的点
代码如下
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root: return None
if root.val == key:
if root.left is None and root.right is None:
return None
elif root.left is None and root.right is not None:
return root.right
elif root.left is not None and root.right is None:
return root.left
else:
cur = root.right
while cur.left is not None:
cur = cur.left
cur.left = root.left
return root.right
if root.val > key:
root.left = self.deleteNode(root.left, key)
if root.val < key:
root.right = self.deleteNode(root.right, key)
return root