二分搜索樹的定義爲:
(1)所有左子樹中的結點小於等於根節點
(2)所有右子樹中的結點大於等於根節點
(3)其任意子樹也滿足(1), (2)
(注意是所有結點)
二分搜索樹刪除結點
主要可以分爲以下三種情況:
(1)被刪除的結點爲葉子結點:直接將其置爲空即可;
(2)被刪除的結點只有左孩子或右孩子,用其左孩子或右孩子替代即可;
(3)被刪除的結點左右孩子都不爲空:可以採取兩種做法:
a. 尋找其左子樹中的最大值,並將當前結點替換爲該值,遞歸在左子樹中刪除該值;
b. 尋找其右子樹中的最小值,並將當前結點替換爲該值,遞歸在右子樹中刪除該值;
代碼實現
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return root;
if(key < root.val) {
root.left = deleteNode(root.left, key);
return root;
}
if(key > root.val) {
root.right = deleteNode(root.right, key);
return root;
}
//1.該結點爲葉子結點,直接刪除
if(root.left == null && root.right == null) {
root = null;
return root;
}
//2.該結點右孩子爲空(左孩子替代)
if(root.left != null && root.right == null) {
root = root.left;
return root;
}
//3.該結點左孩子爲空(右孩子替代)
if(root.right != null && root.left == null) {
root = root.right;
return root;
}
//4.左右孩子都不爲空(挑選左子樹中最大的或者右子樹中最小的,替換當前節點)
if(root.left != null && root.right != null) {
int val = findMaxLeft(root.left);
root.val = val;
root.left = deleteNode(root.left, val);
return root;
}
return root;
}
//尋找以node爲根結點的最大值
private int findMaxLeft(TreeNode node) {
if(node == null) return 0;
if(node.left == null && node.right == null) return node.val;
if(node.right == null) {
return node.val;
}
return findMaxLeft(node.right);
}
}
參考:
LeetCode 450. Delete Node in a BST
https://blog.csdn.net/xiaoxiaoxuanao/article/details/61918125