#include <iostream>
#include <iomanip>
using namespace std;
typedef int ElemType;
typedef struct Node {
ElemType data;
struct Node* lchild, * rchild;//左右孩子
}BiTNode;//二叉树结点
typedef struct {
BiTNode* root;//根节点
int num;
}BiTree;//二叉树
bool Search_BST(BiTree T, ElemType key, BiTNode*& fa, BiTNode*& p);//由p返回值为key的二叉树结点,fa返回它的父节点
bool Insert_BST(BiTree& T, ElemType key);
void Create_BST(BiTree& T);//建立二叉查找树
void Delete_BST(BiTree& T, ElemType key);
void Create_BST(BiTree& T) {
cout << "输入结点个数:" << endl;
int n; cin >> n;
if (n <= 0)return;
T.num = 0; T.root = NULL;//初始化二叉树根节点为空,结点数目为0
cout << "输入结点关键字值:";
ElemType e;
for (int i = 0; i < n; i++) {
cin >> e;
Insert_BST(T, e);
}
}
bool Insert_BST(BiTree& T, ElemType key){
BiTNode* fa, * p;
if (Search_BST(T, key, fa, p))//返回父节点和key所在的p结点,若key已经存在与二叉树内,则不用再插入
return 0;
else {
BiTNode* newNode = new BiTNode;//创建新结点
if (!newNode)exit(0);
newNode->data = key;
newNode->rchild = newNode->lchild = NULL;//初始化新结点左右子树为空
if (!fa)//若未找到key,且返回的父节点为空,则插入的即是父节点
T.root = newNode;
else if (fa->data > key)//若插入值较小则放在二叉树左边
fa->lchild = newNode;
else
fa->rchild = newNode;//若插入值较大则放在二叉树右边
T.num++;
return true;
}
}
bool Search_BST(BiTree T, ElemType key, BiTNode*& fa, BiTNode*& p){
p = T.root; fa = NULL;
while (p) {
if (p->data == key)
return true;
else if (p->data > key) {
fa = p;
p = p->lchild;
}
else {
fa = p;
p = p->rchild;
}
}
return false;
}
void Delete_BST(BiTree& T, ElemType key) {
BiTNode* fa, * p;
Search_BST(T, key, fa, p);
//T有两棵非空子树。可以选择将该结点元素替换成它的左子树的最大元素或右子树的最小元素
//(代码中采用的是前者,即用左子树的最大元素替换被删除的节点),然后在删除被替换的元素。
if (p->lchild && p->rchild) {//若p结点左右子树均存在
BiTNode* q = p;
BiTNode* s = p->lchild;
while (s->rchild) {//找到了s结点,它的值比为p结点小的结点中最大的,它的父节点是q
q = s;
s = s->rchild;
}
p->data = s->data;//将这个值提上来
if (q != p)//s即左子树的最大值点,它的父节点q与结点p不是同一结点,
//也就是说经历了while循环,s是q的右子树,因此s比q大,s的左子树要挂在q的右子树上
q->rchild = s->lchild;
else//s即左子树的最大值点,它的父节点q与结点p是同一结点,
//也就是说只经历了初始化赋值,s是q的左子树,因此s比q小,s的左子树要挂在q的左子树上
q->lchild = s->lchild;
delete s;//s的值已经赋给了p,删除s
}
else {//若p结点左右子树并非均存在
//因此找到p结点的唯一子树,q是唯一子树的父节点,即被删除结点
BiTNode* q = NULL;
if (!p->lchild) {//左子树不存在,唯一子树就是右子树
q = p;
p = p->rchild;
}
else{//左子树存在,唯一子树就是左子树
q = p;
p = p->lchild;
}
if (!fa)//若被删除结点p没有父节点,证明p是根节点,删除根节点后它的唯一子树就是新的根节点
//(在这个条件分支中被删除的结点左右子树并非均存在)
T.root = p;
else {//被删除结点不是根节点
if (fa->lchild == q)//此时的q是被删除结点,那么接下来就很显然了
fa->lchild = p;
else
fa->rchild = p;
}
delete q;
}
T.num--;
}
void preorder(BiTNode* p) {
if (!p)
return;
cout << setw(4) << p->data;
preorder(p->lchild);
preorder(p->rchild);
}
void Preorder(BiTree T) {
cout << setw(4) << T.root->data;
preorder(T.root->lchild);
preorder(T.root->rchild);
}
int main()
{
BiTree T;
Create_BST(T);//建立二叉查找树;
cout << "\n删除前先序遍历:";
Preorder(T);//先序遍历
ElemType key;
cout << "\n输入要查找的元素的关键字:" << endl;
cin >> key;
BiTNode* p, * fa;
if (Search_BST(T, key, fa, p)) {
cout << p->data << "找到了!" << endl;
Delete_BST(T, p->data);
cout << "删除后先序遍历:";
Preorder(T);//先序遍历
}
else {
cout << "没找到!" << endl;
}
return 0;
}
实验样例