50 50
/ \ delete(20) / 30 70 ------------------> 30 70
/ \ / \ \ / \
20 40 60 80 40 60 80
50 50
/ \ delete(30) / 30 70 ------------------> 40 70
\ / \ / \
40 60 80 60 80
50 60
/ \ delete(50) / 40 70 -----------------> 40 70
/ \ \
60 80 80
需要注意的一个重点是:仅当右孩子不为空时,才需要后继节点。在这种特定情况下,可以通过查找右子树的最小值来获取到后继节点。
代码实现:
#include <iostream>
struct Node
{
int key;
Node *left;
Node *right;
};
Node * minValueNode(Node* node)
{
Node* current = node;
//查找最左侧的叶子
while (current->left != NULL)
current = current->left;
return current;
}
//删除二叉搜索树的一个指定节点,并返回新的根节点
Node* deleteNode(Node* root, int key)
{
// base case
if (root == NULL)
return root;
//如果指定值小于根节点值,则这个值处于左子树中。
if (key < root->key)
root->left = deleteNode(root->left, key);
//如果指定值大于根节点值,则这个值处于右子树中。
else if (key > root->key)
root->right = deleteNode(root->right, key);
//找到了匹配的节点
else
{
// 此节点可能有孩子,也可能没有.
// 这里处理只有一个孩子,或者没有孩子的情况
if (root->left == NULL)
{
Node *temp = root->right;
delete root;
return temp;
}
else if (root->right == NULL)
{
Node *temp = root->left;
delete root;
return temp;
}
// 处理有两个孩子的情况: 取得中序遍历中当前节点的后继节点,即右子树中的最小值(最左侧的叶子)。
Node* temp = minValueNode(root->right);
// 将后继节点中的值替换掉匹配节点中的值
root->key = temp->key;
// 删除后继节点
root->right = deleteNode(root->right, temp->key);
}
return root;
}
// 创建一个新的BST节点
Node *createNewNode(int item)
{
Node *temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
// 中序遍历二叉搜索树
void inorder(Node *root)
{
if (root != NULL)
{
inorder(root->left);
std::cout << " " << root->key << " ";
inorder(root->right);
}
}
//插入新节点至二叉搜索树中
Node* insert(Node* node, int key)
{
//空树
if (node == NULL)
return createNewNode(key);
//递归插入。如果已存在指定值,则不插入
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
//返回未修改的node指针
return node;
}
int main()
{
/* 构建一颗如下所示的BST
50
/ 30 70
/ \ / 20 40 60 80
*/
Node *root = NULL;
root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);
std::cout << "Inorder traversal of the given tree \n";
inorder(root);
std::cout << "\nDelete 20\n";
root = deleteNode(root, 20);
std::cout << "Inorder traversal of the modified tree \n";
inorder(root);
std::cout << "\nDelete 30\n";
root = deleteNode(root, 30);
std::cout << "Inorder traversal of the modified tree \n";
inorder(root);
std::cout << "\nDelete 50\n";
root = deleteNode(root, 50);
std::cout << "Inorder traversal of the modified tree \n";
inorder(root);
return 0;
}输出:原文:http://blog.csdn.net/shltsh/article/details/46510115