二叉排序树删除节点C++实现
对应LeetCode
450. 删除二叉搜索树中的节点
思路:找到这个节点,并标记其父节点,根据其在树中的位置做相应的处理,以保证二叉排序树的性质,因为根节点没有父节点,所以需要特殊处理。
TreeNode* deleteNode(TreeNode* root, int key) {
TreeNode* parent = root;
TreeNode* cur = root;
while(cur) {//找到这个节点,并标记它的父节点
if (cur->val > key) {
parent = cur;
cur = cur->left;
} else if (cur->val < key) {
parent = cur;
cur = cur->right;
} else {
break;
}
}
if (cur != nullptr) {//节点存在
if (cur->left == nullptr) {//左子树为空
if (cur->right == nullptr && cur == root) {//为根节点,且左右子树为空
delete cur;
return nullptr;
} else if(cur == parent) {//为根节点,且右子树不空
cur = cur->right;
delete parent;
return cur;
}
else {//不是根节点
parent->left == cur ? parent->left = cur->right : parent->right = cur->right;
delete cur;
cur = nullptr;
}
} else if(cur->right == nullptr) {//右子树为空
if (parent == cur) {//为根节点,且左子树不空
cur = cur->left;
delete parent;
return cur;
}else{//不是根节点
parent->left == cur ? parent->left = cur->left : parent->right = cur->left;
delete cur;
cur = nullptr;
}
} else {//左右都不为空,找到其右子树最小节点/左子树最大节点代替此节点,这里用前者
TreeNode* rightMin = cur->right;
parent = cur->right;
while(rightMin->left != nullptr) {
parent = rightMin;
rightMin = rightMin->left;
}
cur->val = rightMin->val;
if (rightMin == parent) {
cur->right = rightMin->right;
} else {
parent->left = rightMin->right;
}
delete rightMin;
rightMin = nullptr;
}
}
return root;
}