思路:
(1)如果root为空,返回
(2)如果当前结点root是待删除结点:
a:root是叶子结点,直接删去即可
b:root左子树不为空,则找到左子树的最大值,即前驱结点,使用前驱结点代替待删除的root结点值,并在root的左子树中,继续删除前驱结点
c:root右子树不为空,则找到右子树的最大值,即后继结点,使用后继结点代替待删除的root结点值,并在root的右子树中,继续删除后继结点
(3)如果待删除值大于root->val,则在右子树中继续删除待删除值
(4)如果待删除值小于root->val,则在左子树中继续删除待删除值
void deleteTreeNode(TreeNode* &root,int key)//使用引用,以可以直接改变原树的结点 { if(root==NULL) return; if(root->val==key) { if(!root->left && !root->right) { root=NULL; } else if(root->left)//左子树不空就优先左子树吧 { //找左子树的最大元素,,即找到前驱结点 TreeNode* cur=root->left; while(cur->right) cur=cur->right; root->val=cur->val;//使用前驱结点覆盖目标结点,并在目标结点的左子树中删除前驱结点 deleteTreeNode(root->left,cur->val); } else if(root->right)//右子树不空就优先左子树吧 { //找右子树的最大元素,,即找到后继结点 TreeNode* cur=root->right; while(cur->left) cur=cur->left; root->val=cur->val;//使用后继结点覆盖目标结点,并在目标结点的右子树中删除后继结点 deleteTreeNode(root->right,cur->val); } } else if(key < root->val) { deleteTreeNode(root->left,key); } else if(key > root->val) { deleteTreeNode(root->right,key); } }
要注意,上面递归的过程中使用的是root的引用,因为是要直接删除结点,而不是改变结点中的值。