235. 二叉搜索树的最近公共祖先
二叉搜索树和一般的二叉树之间的区别:
可以进行大小的判断,和这个结点相比有何种变化。
如果p和q在x的两边则说明x是公共祖先,如果p和q在x的左右两边则说明公共祖先在左子树或者右子树中,把握住二叉搜索树的特点。
迭代法: 由于二叉搜索树已经确定了搜索方向,所以利用迭代法在本题中也变得非常简单。
返回的值: 左右子树中是否存在p和q的值。
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
# 使用递归的方式不需要
def traversal(root,p,q):
if not root:
return None
# 向左右遍历的情况
if root.val > p.val and root.val > q.val:
left = traversal(root.left,p,q)
if left: return left
elif root.val < p.val and root.val < q.val:
right = traversal(root.right,p,q)
if right : return right
# 剩余的代码
else:
return root
701.二叉搜索树中的插入操作
插入一个结点并且树的结构也不是唯一的只需要在叶子结点上插入新的结点即可。
终止条件: 找到可以插入结点的位置,如果发现当前结点为空则可以插入此结点。
返回值: 插入新的结点之后,这颗二叉树得新的根节点。
思路: 只需要不断返回
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
def insert(root,val):
if not root:
p = TreeNode(val = val)
return p
if root.val > val:
root.left = insert(root.left,val)
else:
root.right = insert(root.right,val)
# 需要将叶子结点传给上一层结点,从而实现逐步改变根节点得值。
return root
if not root:
p = TreeNode(val = val)
return p
insert(root,val)
return root
450.删除二叉搜索树中的节点
几种情况:
- 没找到删除得结点
- 删除得结点是叶子结点(左空右空)
- 删除得结点左(左空右不空)
- 删除得结点左(左不空右空)
- 删除得结点左(左不空右不空)如果是此种情况需要调整二叉搜索树得结构,妥善安置删除结点得左结点即可。
思路:强调一层一层将结点向上传导。
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root : return None # 节点为空,返回
if root.val < key :
root.right = self.deleteNode(root.right, key)
elif root.val > key :
root.left = self.deleteNode(root.left, key)
# 如果结点的值相同开始删除结点的操作
else:
# 当前节点的左子树为空,返回当前的右子树
if not root.left : return root.right
# 当前节点的右子树为空,返回当前的左子树
if not root.right: return root.left
# 左右子树都不为空,找到右孩子的最左节点 记为p
node = root.right
while node.left :
node = node.left
# 将当前节点的左子树挂在p的左孩子上
node.left = root.left
# 当前节点的右子树替换掉当前节点,完成当前节点的删除
root = root.right
return root