【二叉树】删除二叉搜索树中的节点
原创
©著作权归作者所有:来自51CTO博客作者haocold的原创作品,请联系作者获取转载授权,否则将追究法律责任
0x00 题目
定一个二叉搜索树的根节点 root
和一个值 key
删除二叉搜索树中的 key
对应的节点
并保证二叉搜索树的 性质
不变
返回二叉搜索树(有可能被更新)的 根节点
的引用
一般来说,删除节点可分为 两个
步骤:
首先 找到
需要删除的节点
如果找到了 删除
它
0x01 思路
删除节点,要分以下几种情况:
1.节点恰好是 末端
节点,两个 子节点
都为 空
直接返回 nil
,替换当前节点
if (root.left == nil && root.right == nil) {
return nil
}
2.节点只有 一个
非空
子节点
那么要让这个孩子接替自己的位置
if (root.left == nil) { return root.right }
if (root.right == nil) { return root.left }
3.节点有 两个
子节点,为了不破坏 BST 的性质
必须找到 左子树
中 最大
的那个节点
或者 右子树
中 最小
的那个节点来接替自己
// 找到右子树的最小节点
let minNode = getMinNode(root.right!)
// 把 root 改成 minNode
root.val = minNode.val
// 转而去删除 minNode
root.right = deleteNode(root.right, minNode.val)
0x02 解法
语言:Swift
树节点:TreeNode
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
public init() { self.val = 0; self.left = nil; self.right = nil; }
public init(_ val: Int) { self.val = val; self.left = nil; self.right = nil; }
public init(_ val: Int, _ left: TreeNode?, _ right: TreeNode?) {
self.val = val
self.left = left
self.right = right
}
}
解法:
func deleteNode(_ root: TreeNode?, _ key: Int) -> TreeNode? {
guard let root = root else { return nil }
// 比根节点大,往右边找
if (root.val < key) {
root.right = deleteNode(root.right, key)
}
// 比根节点小,往左边找
else if (root.val > key) {
root.left = deleteNode(root.left, key)
}
// 找到了!
else if (root.val == key) {
// 情况1 和 情况 2
if (root.left == nil) { return root.right }
if (root.right == nil) { return root.left }
// 情况 3
// 找到最小的节点
let minNode = getMinNode(root.right!)
// 替换值
root.val = minNode.val
// 删除 子树中的最小的节点
root.right = deleteNode(root.right, minNode.val)
}
return root
}
// 查找最小的节点
func getMinNode(_ root: TreeNode) -> TreeNode {
var node = root
while (node.left != nil) {
node = node.left!
}
return node
}
0x03 我的作品
欢迎体验我的作品之一:小五笔
五笔学习好帮手!
App Store
搜索即可~