方法一:用后继代替被删除结点
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root)
return NULL;
if(key < root->val){
root->left=deleteNode(root->left,key);
return root;
}
else if(key > root->val){
root->right=deleteNode(root->right,key);
return root;
}
else{ //key == root->val ,找到该结点
if(root->right==NULL){ //右子树为空
TreeNode* l=root->left;
root->left=NULL;
return l;
}
if(root->left==NULL){ //左子树为空
TreeNode* r=root->right;
root->right=NULL;
return r;
}
//左右子树都不为空,将右子树最小结点代替该节点
TreeNode* rMin = MinNode(root->right); //找到右子树最小结点
rMin->right = removeMin(root->right);
rMin->left=root->left;
return rMin;
}
}
private:
TreeNode* MinNode(TreeNode* node){ //寻找node为根的最小结点
while(node->left)
node=node->left;
return node;
}
TreeNode* removeMin(TreeNode* node){ //删除node为根的最小结点
if(node->left==NULL) //结束递归的条件:左子树为空,根节点最小,返回右子树
return node->right;
node->left=removeMin(node->left);
return node;
}
};
方法二:用前驱代替被删除结点
class Solution {
public:
TreeNode* deleteNode(TreeNode* root, int key) {
if(!root)
return NULL;
if(key < root->val){
root->left=deleteNode(root->left,key);
return root;
}
else if(key > root->val){
root->right=deleteNode(root->right,key);
return root;
}
else{ //key == root->val ,找到该结点
if(root->right==NULL) //右子树为空
return root->left;
if(root->left==NULL) //左子树为空
return root->right;
//左右子树都不为空,将左子树最大结点代替该节点
TreeNode* lMax = MaxNode(root->left); //找到左子树最大结点
lMax->left=removeMax(root->left);
lMax->right = root->right;
return lMax;
}
}
private:
TreeNode* MaxNode(TreeNode* node){ //寻找node为根的最大结点
while(node->right)
node=node->right;
return node;
}
TreeNode* removeMax(TreeNode* node){ //删除node为根的最大结点
if(node->right==NULL) //结束递归的条件:右子树为空,根节点最大,返回左子树
return node->left;
node->right=removeMax(node->right);
return node;
}
};
注意:lMax->left=removeMax(root->left);
lMax->right = root->right;
两句不能颠倒,否则会超时。因为先执行后一句删除的最大值是错误的,root->right的最大值。