List: 235. 二叉搜索树的最近公共祖先,701.二叉搜索树中的插入操作,450.删除二叉搜索树中的节点
235. 二叉搜索树的最近公共祖先lowest-common-ancestor-of-a-binary-search-tree,701.二叉搜索树中的插入操作insert-into-a-binary-search-tree,450.删除二叉搜索树中的节点delete-node-in-a-bst
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
def traversal(cur, p, q):
if not cur:
return
if cur.val > p.val and cur.val > q.val:
left = traversal(cur.left, p, q)
if left:
return left
if cur.val < p.val and cur.val < q.val:
right = traversal(cur.right, p, q)
if right:
return right
return cur
return traversal(root, p, q)
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, x):
# self.val = x
# self.left = None
# self.right = None
class Solution:
def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
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:
return root
return None
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
node = TreeNode(val)
return node
if root.val > val:
root.left = self.insertIntoBST(root.left, val)
if root.val < val:
root.right = self.insertIntoBST(root.right, val)
return root
在迭代法遍历的过程中,需要记录一下当前遍历的节点的父节点,这样才能做插入节点的操作。
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def insertIntoBST(self, root: Optional[TreeNode], val: int) -> Optional[TreeNode]:
if not root:
node = TreeNode(val)
return node
cur = root
parent = root
while cur: # 需要记录上一个节点的值,否则无法赋值新节点
parent = cur
if cur.val > val:
cur = cur.left
else:
cur = cur.right
node = TreeNode(val)
if val < parent.val: # 赋值
parent.left = node
else:
parent.right = node
return root
# Definition for a binary tree node.
# class TreeNode:
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution:
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root:
return
if root.val == key:
if not root.left and not root.right:
return
elif root.left and not root.right:
return root.left
elif not root.left and root.right:
return root.right
else:
cur = root.right
while cur.left:
cur = cur.left
cur.left = root.left
return root.right
if key < root.val:
root.left = self.deleteNode(root.left, key)
if key > root.val:
root.right = self.deleteNode(root.right,key)
return root
力扣 450 题“删除二叉搜索树中的节点”要求在给定的二叉搜索树(BST)中删除值为 key
的节点,并返回删除节点后的二叉搜索树的根节点。在删除节点时,需要保证删除操作后树仍然是一棵二叉搜索树。
该代码采用迭代的方式先找到要删除的节点,然后通过一个辅助函数 deleteOneNode
来处理删除节点的逻辑,最后根据删除节点与父节点的关系更新父节点的指针。
deleteOneNode
def deleteOneNode (self, target: TreeNode) -> TreeNode:
"""
将目标节点(删除节点)的左子树放到目标节点的右子树的最左面节点的左孩子位置上
并返回目标节点右孩子为新的根节点
"""
if not target:
return
if not target.right:
return target.left
cur = target.right
while cur.left:
cur = cur.left
cur.left = target.left
return target.right
target
为空,直接返回 None
。while
循环找到目标节点右子树的最左节点。deleteNode
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
if not root:
return
cur = root
pre = None
while cur:
if cur.val == key:
break
pre = cur
if cur.val > key:
cur = cur.left
else:
cur = cur.right
if not pre:
return self.deleteOneNode(cur)
if pre.left and pre.left.val == key:
pre.left = self.deleteOneNode(cur)
if pre.right and pre.right.val == key:
pre.right = self.deleteOneNode(cur)
return root
deleteOneNode
函数进行删除操作。None
。while
循环遍历二叉搜索树,cur
指针指向当前节点,pre
指针指向 cur
的父节点。当 cur.val == key
时,找到要删除的节点,跳出循环。pre
为空,说明要删除的节点是根节点,直接调用 deleteOneNode
函数处理,并返回处理后的结果。cur
是 pre
的左子节点还是右子节点,更新 pre
的相应指针。假设二叉搜索树如下:
5
/ \
3 6
/ \ \
2 4 7
要删除值为 3 的节点,具体步骤如下:
deleteOneNode
函数处理值为 3 的节点:
5
/ \
4 6
/ \
2 7
通过这种方式,就完成了在二叉搜索树中删除指定节点的操作。
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if (root == nullptr) return root;
if (root->val == key) {
if (root->right == nullptr) { // 这里第二次操作目标值:最终删除的作用
return root->left;
}
TreeNode *cur = root->right;
while (cur->left) {
cur = cur->left;
}
swap(root->val, cur->val); // 这里第一次操作目标值:交换目标值其右子树最左面节点。
}
root->left = deleteNode(root->left, key);
root->right = deleteNode(root->right, key);
return root;
}
};