二叉查找树某个结点的左子树的值都比它小,其右子树的值比它大。
这里主要讲解下删除算法中的第三种情况
3.1
3.2
要实现的主要操作
代码实现
#include <iostream>using namespace std;
// BST的结点
typedef struct node
{
int key;
struct node *lChild, *rChild,*parent;
}Node;
typedef struct BST
{
Node *root;
}BST;
void createBST(BST p);
// 在给定的BST中插入结点,其数据域为element, 使之称为新的BST
void Insert(BST *p, Node *z)
{
Node *y=NULL;
Node * x=p->root;
while(x!=NULL)
{
y=x;
if(z->key<x->key)
x=x->lChild;
else
x=x->rChild;
}
z->parent=y;
if(y==NULL)
p->root=z;
else if(z->key<y->key)
y->lChild=z;
else
y->rChild=z;
}
void PrintBST(Node *root,int depth)
{
Node *p1=root;
if(p1==NULL)
printf("这是一颗空树!\n");
else
{
int i;
if (p1->rChild)
PrintBST(p1->rChild, depth + 1);
for (i = 1; i <= depth; i++)
printf(" ");
printf("%d\n", p1->key);
if (p1->lChild)
PrintBST(p1->lChild, depth + 1);
}
}
void createBST(BST *p)
{
int t;
int depth = 0;
printf("\n请输入关键字(以-123结束建立平衡二叉树):");
scanf("%d", &t);
while (t != -123)
{
Node *z=new Node;
z->key=t;
z->lChild=z->rChild=z->parent=NULL;
Insert(p, z);
printf("\n请输入关键字(以-123结束建立平衡二叉树):");
scanf("%d", &t);
}
printf("\n****************************************************\n");
printf("*******************您创建的二叉树为*******************\n");
if (p)
PrintBST(p->root,depth);
else
printf("这是一棵空树!\n");
printf("********************二叉树创建完成*********************\n");
}
Node* search(Node *root, int key)
{
if (root == NULL)
{
printf("此树为空!\n");
return NULL;
}
else if (key == root->key)
{
printf("查找成功!,%d的地址是%p\n", key, root);
return root;
}
else if (key < root->key)
search(root->lChild, key);
else
search(root->rChild, key);
}
void preorderBST(Node* root)
{
if (root)
{
cout << root->key << " ";
preorderBST(root->lChild);
preorderBST(root->rChild);
}
}
//中序遍历(这个可以做为排序算法
void inorderBST(Node *root)
{
if (root)
{
inorderBST(root->lChild);
cout << root->key << " ";
inorderBST(root->rChild);
}
}
//后序遍历
void postrderBST(Node* root)
{
if (root)
{
postrderBST(root->lChild);
postrderBST(root->rChild);
cout << root->key << " ";
}
}
void Delete(BST* p,int key)
{
Node* p1=p->root;
//删除要分三种情况
while(p1->key!=key)
{
if(key>p1->key)
p1=p1->rChild;
else
p1=p1->lChild;
}
//第一种情况:如果z没有孩子结点,则只是简单的将它删除,并修改它的父节点。用NIL作为孩子来替换z(现在还没有考虑其为根节点)
if(p1->lChild==NULL&&p1->rChild==NULL)
{
if(p1==p->root)
{
printf("已经删除根节点!,此时树为空哦\n");
p->root=NULL;
return;
}
if(p1->key<p1->parent->key)
p1->parent->lChild=NULL;
else
p1->parent->rChild=NULL;
}
//第二种情况:如果只有一个孩子,则将这个孩子提升到树中z的位置上,并修改z的父节点,用z的孩子来替换z
if(p1->lChild!=NULL&&p1->rChild==NULL)
{
if(p1==p->root)
{
p->root=p1->lChild;
return;
}
if(p1->key<p1->parent->key)
{
p1->parent->lChild=p1->lChild;
p1->lChild->parent=p1->parent;
}
else
{
p1->parent->rChild=p1->lChild;
p1->lChild->parent=p1->parent;
}
}
if(p1->rChild!=NULL&&p1->lChild==NULL)
{
if(p1==p->root)
{
p->root=p1->rChild;
return;
}
if(p1->key<p1->parent->key)
{
p1->parent->lChild=p1->rChild;
p1->rChild->parent=p1->parent;
}
else
{
p1->parent->rChild=p1->rChild;
p1->rChild->parent=p1->parent;
}
}
//第三种情况(这个节点既有左子树也有右子树)
if(p1->lChild!=NULL&&p1->rChild!=NULL)
{
Node *y=p1->rChild;
if(y->lChild!=NULL)
{
while(y->lChild!=NULL)
y=y->lChild;
//先用y的右孩子替换y(如果y有右孩子x,就把x作为y的父节点r的左孩子,否则就将y的父节点r的左孩子置为空)
if(y->rChild!=NULL)
{
y->rChild->parent=y->parent;
y->parent->lChild=y->rChild;
}
else
{
y->parent->lChild=NULL;
}
//用y替换z
y->rChild=p1->rChild;
p1->rChild->parent=y;
y->lChild=p1->lChild;
p1->lChild->parent=y;
y->parent=p1->parent;
if(p1==p->root)
{
p->root=y;
}
else
{
if(p1->parent->key>p1->key)
p1->parent->lChild=y;
else
p1->parent->rChild=y;
}
}
else
{
y->lChild=p1->lChild;
p1->lChild->parent=y;
y->parent=p1->parent;
if(p1==p->root)
{
p->root=y;
}
else
{
if(p1->parent->key>p1->key)
p1->parent->lChild=y;
else
p1->parent->rChild=y;
}
}
}
}
void Maximum(Node* root)
{
Node* p1=root;
while(p1->rChild)
{
p1=p1->rChild;
}
printf("Maximum=%d",p1->key);
}
void Minmum(Node * root)
{
Node* p1=root;
while(p1->lChild)
{
p1=p1->lChild;
}
printf("Minimum=%d",p1->key);
}
void get_parent(Node *p)
{
if (p)
{
printf("%d->parent=%p",p->key,p->parent);
get_parent(p->lChild);
get_parent(p->rChild);
}
}
int main(void)
{
int ch;
BST *T=new BST;
T->root=NULL;
printf("请写入您要建立的BST树的所有结点值!\n");
createBST(T);
while (1)
{
printf("\n***************************************\n");
printf("*****按下列选项选择您要进行的操作******\n");
printf("*****1前序输出.************************\n");
printf("*****2.中序输出************************\n");
printf("*****3.后序输出************************\n");
printf("*****4.查找****************************\n");
printf("*****5.求最大值************************\n");
printf("*****6.求最小值************************\n");
printf("*****7.插入数值************************\n");
printf("*****8.获得父节点地址******************\n");
printf("*****9.删除数值************************\n");
printf("*****10.打印排序二叉树*****************\n");
printf("*****11.退出***************************\n");
printf("***************************************\n");
scanf("%d", &ch);
switch (ch)
{
case 1:
preorderBST(T->root); break;
case 2:
inorderBST(T->root); break;
case 3:
postrderBST(T->root);break;
case 4:
{
int m;
printf("您要查找的是多少:");
scanf("%d", &m);
search(T->root, m);
}
break;
case 5:
Maximum(T->root); break;
case 6:
Minmum(T->root);break;
case 7:
{
printf("您要插入多少:");
int key;
scanf("%d",&key);
Node *z=new Node;
z->key=key;
z->lChild=z->rChild=z->parent=NULL;
Insert(T,z);
}break;
case 8:
get_parent(T->root);
break;
case 9:
{
printf("您要删除多少:");
int key;
scanf("%d",&key);
Delete(T,key);
}
break;
case 10:
PrintBST(T->root,0);
break;
case 11:
return 0; break;
default:
break;
}
}
return 0;
}
代码展示大家可以自己运行,初始数据是4,2,1,3,5,9,7,6,比较容易测试。
删除操作详解