mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-11 21:10:58 +08:00
Update 0450.删除二叉搜索树中的节点.md
This commit is contained in:
@ -324,88 +324,90 @@ class Solution {
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
递归法(版本一)
|
||||
```python
|
||||
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 :
|
||||
def deleteNode(self, root, key):
|
||||
if root is None:
|
||||
return root
|
||||
if root.val == key:
|
||||
if root.left is None and root.right is None:
|
||||
return None
|
||||
elif root.left is None:
|
||||
return root.right
|
||||
elif 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)
|
||||
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
|
||||
if root.val < key:
|
||||
root.right = self.deleteNode(root.right, key)
|
||||
return root
|
||||
```
|
||||
|
||||
**普通二叉树的删除方式**
|
||||
递归法(版本二)
|
||||
```python
|
||||
class Solution:
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
if not root: return root
|
||||
if root.val == key:
|
||||
if not root.right: # 这里第二次操作目标值:最终删除的作用
|
||||
def deleteNode(self, root, key):
|
||||
if root is None: # 如果根节点为空,直接返回
|
||||
return root
|
||||
if root.val == key: # 找到要删除的节点
|
||||
if root.right is None: # 如果右子树为空,直接返回左子树作为新的根节点
|
||||
return root.left
|
||||
tmp = root.right
|
||||
while tmp.left:
|
||||
tmp = tmp.left
|
||||
root.val, tmp.val = tmp.val, root.val # 这里第一次操作目标值:交换目标值其右子树最左面节点。
|
||||
|
||||
root.left = self.deleteNode(root.left, key)
|
||||
root.right = self.deleteNode(root.right, key)
|
||||
cur = root.right
|
||||
while cur.left: # 找到右子树中的最左节点
|
||||
cur = cur.left
|
||||
root.val, cur.val = cur.val, root.val # 将要删除的节点值与最左节点值交换
|
||||
root.left = self.deleteNode(root.left, key) # 在左子树中递归删除目标节点
|
||||
root.right = self.deleteNode(root.right, key) # 在右子树中递归删除目标节点
|
||||
return root
|
||||
|
||||
```
|
||||
|
||||
**迭代法**
|
||||
```python
|
||||
class Solution:
|
||||
def deleteNode(self, root: Optional[TreeNode], key: int) -> Optional[TreeNode]:
|
||||
# 找到节点后分两步,1. 把节点的左子树和右子树连起来,2. 把右子树跟父节点连起来
|
||||
# root is None
|
||||
if not root: return root
|
||||
p = root
|
||||
last = None
|
||||
while p:
|
||||
if p.val==key:
|
||||
# 1. connect left to right
|
||||
# right is not None -> left is None | left is not None
|
||||
if p.right:
|
||||
if p.left:
|
||||
node = p.right
|
||||
while node.left:
|
||||
node = node.left
|
||||
node.left = p.left
|
||||
right = p.right
|
||||
else:
|
||||
# right is None -> right=left
|
||||
right = p.left
|
||||
# 2. connect right to last
|
||||
if last==None:
|
||||
root = right
|
||||
elif last.val>key:
|
||||
last.left = right
|
||||
else:
|
||||
last.right = right
|
||||
# 3. return
|
||||
def deleteOneNode(self, target: TreeNode) -> TreeNode:
|
||||
"""
|
||||
将目标节点(删除节点)的左子树放到目标节点的右子树的最左面节点的左孩子位置上
|
||||
并返回目标节点右孩子为新的根节点
|
||||
是动画里模拟的过程
|
||||
"""
|
||||
if target is None:
|
||||
return target
|
||||
if target.right is None:
|
||||
return target.left
|
||||
cur = target.right
|
||||
while cur.left:
|
||||
cur = cur.left
|
||||
cur.left = target.left
|
||||
return target.right
|
||||
|
||||
def deleteNode(self, root: TreeNode, key: int) -> TreeNode:
|
||||
if root is None:
|
||||
return root
|
||||
cur = root
|
||||
pre = None # 记录cur的父节点,用来删除cur
|
||||
while cur:
|
||||
if cur.val == key:
|
||||
break
|
||||
pre = cur
|
||||
if cur.val > key:
|
||||
cur = cur.left
|
||||
else:
|
||||
# Update last and continue
|
||||
last = p
|
||||
if p.val>key:
|
||||
p = p.left
|
||||
else:
|
||||
p = p.right
|
||||
cur = cur.right
|
||||
if pre is None: # 如果搜索树只有头结点
|
||||
return self.deleteOneNode(cur)
|
||||
# pre 要知道是删左孩子还是右孩子
|
||||
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
|
||||
```
|
||||
|
||||
|
Reference in New Issue
Block a user