1. 思路分析
这个题是比较复杂的,原因是删除节点后,最终的二叉树依旧是一棵二叉搜索树。
难点:
- 如何定位到要删除的节点?
- 删除节点后,二叉树如何移动使其依旧是一棵二叉搜索树?
二叉搜索树性质:
- 中序搜索默认是升序集合;
- 所有左子树节点都比root节点小,所有右子树节点都比root节点大
思路:
1. 方法的返回值:是删除节点后返回的新的root节点。
知识点:利用二叉搜索树的性质,可以只搜索半条边就定位到待删除节点的位置,注意需要重新建立指针关系。
2. 删除节点后,新root节点为左子树的最大节点或者右子树最小节点。
知识点:转换为获取二叉树右子树最小节点的题型,将右子树最小节点的值赋值给待删除的节点,然后删除右子树最小节点。
3. 如何找到右子树最小节点?
二叉搜索树中序遍历是有序的,即最左子树为最小节点。
private TreeNode min(TreeNode root){
if(root.left==null){
return root;
}
return min(root.left);
}
2. 结题算法
2.1 寻找右子树最小节点
节点一直向左子树遍历,左子树遇到空时,表示遍历到了末尾。即最小节点。
private TreeNode min(TreeNode root){
if(root.left==null){
return root;
}
return min(root.left);
}
2.2 删除右子树最小节点
删除右子树最小节点后,并返回root节点
由此操作得到的二叉树依旧是二叉搜索树。
- 二叉搜索树性质:所有左子树小于root节点,所有右子树大于root节点。
(1)最小节点的左子树为空,即没有比它更小的节点;
(2)最小节点右子树节点依旧小于最小节点的root节点;
(3)删除最小节点后,将最小节点的right节点挂在最小节点父结点的left指针上。
注意:递归方法返回的是最小结点的right结点。然后最小结点的父结点left指针由最小结点指向最小结点的右孩子。完成最小结点的删除。
//删除最小节点后,返回root节点
private TreeNode delMin(TreeNode root){
if(root.left==null){
return root.right;
}
root.left=delMin(root.left);
return root;
}
2.3 二分搜索值
- 若key大于root节点的值,那么待删除的节点在右子树;
1.1 递归方法返回的是删除后的节点,使用root重建树; - 若key小于root节点的值,那么待删除的节点在左子树。
2.1 递归方法返回的是删除后的节点,使用root重建树; - 若key等于root节点的值:
3.1 若root是叶子节点,直接删除;
3.2 若root是单子树节点,那么返回子树的后续节点(即把root节点删除后输出)
3.3 若root存在左右子树:
-3.3.1 找到右子树的最小节点;
-3.3.2 删除右子树最小节点,并返回root节点;
-3.3.3 使用右子树最小节点的值替换待删除节点的值;
3. 最终结果
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root==null){
return null;
}
//左子树寻找节点
if(key<root.val){
//左子树得到删除后的节点
TreeNode newLeft= deleteNode(root.left,key);
root.left=newLeft;
return root;
}else if(key>root.val){
//右子树得到删除后的节点
TreeNode newRight= deleteNode(root.right,key);
root.right=newRight;
return root;
}else{
//找到节点后,替换节点,删除右子树最小节点
//1. 若是叶子节点,直接删除
if(root.left==null&&root.right==null){
return null;
}
//2. 若是左子树节点
else if(root.left!=null&&root.right==null){
return root.left;
}
else if(root.right!=null&&root.left==null){
return root.right;
}
//两个节点同时存在时
else{
//寻找右子树最小节点
TreeNode node = min(root.right);
//删除右子树最小节点,并返回根节点,root的右节点指向新的子树节点
root.right = delMin(root.right);
//替换节点
root.val=node.val;
return root;
}
}
}
//获取最小节点
private TreeNode min(TreeNode root){
if(root.left==null){
return root;
}
return min(root.left);
}
//删除最小节点后,返回root节点
private TreeNode delMin(TreeNode root){
if(root.left==null){
return root.right;
}
root.left=delMin(root.left);
return root;
}
}
网友评论