235. 二叉搜索树的最近公共祖先
1. 遍历根节点的时候,当前遍历的节点比p跟q都大的话,公共祖先在当前遍历节点的左子树里
2. 如果p跟q比当前遍历的节点都小的话,说明在右子树中
3. 如果当前遍历的值在p跟q之间,那么这个就是公共节点
# 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 lowestCommonAncestor(self, root, p, q):
"""
:type root: TreeNode
:type p: TreeNode
:type q: TreeNode
:rtype: TreeNode
"""
def traversal(cur,p,q):
# recursion stop condition
if cur == None:
# the node is empty,it won't have common ancestor
return cur
# single recursion logic
if(cur.val > p.val and cur.val > q.val):
# we need to search left sub tree
left = traversal(cur.left,p,q)
# check if we find node or not
if(left is not None):
# we find common ancestor
return left
# iterate right
elif(cur.val < p.val and cur.val < q.val):
right = traversal(cur.right,p,q)
# check we find ancestor or not
if(right is not None):
return right
else:
# current node val is between p and q, mean's it must be common ancestor
return cur
return traversal(root,p,q)
701.二叉搜索树中的插入操作
1. 递归停止条件:当传递的节点为空时,我们就可以插入新节点了,创建一个值为val的节点并return
2. 利用二叉树特性,当前值大于题目给的val说明要搜索左子树,我们对左边进行递归
3. 如果当前值小于val,则递归右边,用root.right/root.left去接受值
4. 最后返回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 insertIntoBST(self, root, val):
"""
:type root: TreeNode
:type val: int
:rtype: TreeNode
"""
def traversal(node,val):
# recursion stop condition
if node is None:
# create new node
new_node = TreeNode(val)
# when we meet none,means we should insert node
return new_node
# recursion for single traversal
if node.val > val:
# mean's search left side tree
node.left = traversal(node.left,val)
if node.val < val:
# mean's search right side tree
node.right = traversal(node.right,val)
return node
return traversal(root,val)
450.删除二叉搜索树中的节点
1. 没找到要删除的节点
2. 找到删除的点
1. 删除的点是叶子节点
1. 左为空右也为空
2. 左不为空,右为空
1. 让父节点直接指向左孩子
3. 左为空,右不空
1. 让父节点直接指向右孩子
4. 左不空,右不空
1. 让左右孩子其中一个继承父节点的位置,
1. 如果让右孩子继承父节点位置,让左子树放在继承位置之前右子树的左孩子的下面
2. 因为只有这个节点的值是要比父节点大一个数
C++ 伪代码
TreeNode * delete(root,key){
// 递归停止条件; 删除的节点就是我们的停止条件
if(root == Null){
// 遍历到空了,返回null没找到要删除的节点
return null
}
// 找到了删除的节点
if(root->val == key){
// 如果为叶子节点
if(root->left == null && root->right == null){
// 删除叶子节点,也就是说叶子节点的上一个节点会指向null
// 这个 null在本层递归之后,会在下面有当前层的左子树等于下一层递归的返回值
return null
}
// 左不为空,右为空
else if(root->left != null && root->right == null){
// 让删除的节点的左子树向上一层返回,这样要删除的节点就会被移除,
// 因为删除节点上面的节点会接住 删除节点的返回值,这里的返回值就是删除节点的左子树
return root.left
}
// 左为空,右为空
else if(root->left == null && root->right != null){
// 逻辑跟上面一样
return root->right
}
//左不空,右不空
else{
// 找到父节点右子树左孩子的值
cur = root->right // 当前要删除的节点的右孩子
// 只要当前节点左侧不为空就一直移动,直到叶子节点为止
while cur->left != null{
cur = cur->left
}
// 处理要移动的左子树
cur->left = root->left
// 这里移动完左子树之后,要删除节点的情况就是左为空,右不为空的情况,所以直接return root->right
return root->right
}
}
// 单层递归的逻辑
if(key < root->val){
// 向左侧搜索;
// 根节点应该指向,它的左子树删除掉key节点之后新的这个根节点返回给根节点
root->left = delete(root->left,key)
}
if(key > root->val){
// 向右搜索
root->right = delete(root->right,key)
}
// 左右子树都处理完了,返回根节点
return 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 deleteNode(self, root, key):
"""
:type root: TreeNode
:type key: int
:rtype: TreeNode
"""
# recursion end condition
if root is None:
# we finished recursion, but can not find the node we want delete
return root
# we find the node we want delete
if root.val == key:
# if delete node is leaft node
if root.left == None and root.right == None:
# we let the child node pointer to none
return None
# if delete node right is empty
elif root.left != None and root.right == None:
# parent node we pointer to left node
return root.left
elif root.left == None and root.right == None:
return root.right
else:
# left and right both are NOT empty
cur = root.right # use cur to store are right tree
# until reach the pare node right sub tree left side to empty
while cur.left:
cur = cur.left
# move are left sub tree
cur.left = root.left
# after move the left sub tree to right sub tree child node
# the situtaion is same as left empty right is not empty
return root.right
# recursion
if key < root.val:
# search to left
root.left = self.deleteNode(root.left,key)
if key > root.val:
# search to right
root.right = self.deleteNode(root.right,key)
# finished process left and right, return root
return root