1、题目
2、分析
思路一:使用层序遍历。可以记录下父节点的地址。方便节点删除后,拼接父节点和子树。不过要处理的特殊情况比较多。
思路二:使用递归的处理。比较简洁、好理解。只需要处理三种情况就行(要删除的节点是叶子节点、要删除的节点只有一个子树、要删除的节点有两个子树)
3、代码
思路一:层序遍历
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
TreeNode fatherNode = null;
TreeNode thisNode = null;
TreeNode leftNode = null;
TreeNode rightNode = null;
int leftFlag = 0;
int rightFlag = 0;
Queue<TreeNode> queue = new LinkedList<>();
queue.add(root);
//找到要删除的节点
while(!queue.isEmpty()){
int size = queue.size();
for(int i = 0; i < size; i++){
TreeNode node = queue.poll();
if(node.val == key){
thisNode = node;
leftNode = node.left;
rightNode = node.right;
break;
}
if(node.left != null){
queue.add(node.left);
if(node.left.val == key) {
leftFlag = 1;
fatherNode = node;
}
}
if(node.right != null){
queue.add(node.right);
if(node.right.val == key) {
rightFlag = 1;
fatherNode = node;
}
}
}
if(thisNode != null) break;
}
//判断要删除的节点,是在父节点的左还是右
if(thisNode == null) return root;
if(leftFlag != 0){
if(rightNode != null){
fatherNode.left = rightNode;
}
else
{
fatherNode.left = leftNode;
}
}
if(rightFlag != 0){
if(rightNode != null){
fatherNode.right = rightNode;
}
else
{
fatherNode.right = leftNode;
}
}
//把要删除的节点的左子树,接到要删除节点右子树下的最左节点(也就是右子树中的最小节点)
while(rightNode != null && rightNode.left != null){
rightNode = rightNode.left;
}
if(rightNode != null) rightNode.left = leftNode;
//特殊情况:要删除的节点是跟节点,而且只有左或者右子树
if(fatherNode == null && thisNode.right != null) {
return thisNode.right;
}
else if(fatherNode == null && thisNode.left != null){
return thisNode.left;
}
//特殊情况:只有一个根节点,并且要删除的是根节点
else if(fatherNode == null && thisNode.left == null && thisNode.right == null){return null;}
else{
return root;
}
}
}
递归解法(简洁、容易理解):
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode deleteNode(TreeNode root, int key) {
if(root == null) return null;
if(root.val == key){
//该节点是叶子节点
if(root.left == null && root.right == null) return null;
//该节点只有一个孩子
if(root.left == null && root.right != null) return root.right;
if(root.left != null && root.right == null) return root.left;
//该节点有两个孩子
TreeNode minNode = getMinNode(root.right);
root.val = minNode.val;
root.right = deleteNode(root.right, minNode.val);
}
if(root.val > key){
root.left = deleteNode(root.left, key);
}
else{
root.right = deleteNode(root.right, key);
}
return root;
}
private TreeNode getMinNode(TreeNode root){
while(root.left != null)
{
root = root.left;
}
return root;
}
}