/*
*二叉排序树:二级指针
*/
#include<stdio.h>
#include<stdlib.h>
typedef struct
{
int key;
int others;
}elemtype;
typedef struct bitnode
{
elemtype data;
struct bitnode *lchild,*rchild;
}*bitree;
int init(bitree *bt)
{
*bt=NULL;
return 1;
}
void destroy(bitree *bt)
{
if(*bt)
{
if((*bt)->lchild)
destroy(&(*bt)->lchild);
if((*bt)->rchild)
destroy(&(*bt)->rchild);
free(*bt);
*bt=NULL;
}
}
bitree search(bitree bt,int key)
{
if((!bt)||key==bt->data.key)
return bt;
else if(key<bt->data.key)
return search(bt->lchild,key);
else
return search(bt->rchild,key);
}
void search_1(bitree *bt,int key,bitree f,bitree *p,int *flag)
{
if(!*bt)
{
*p=f;
*flag=0;
}
else if(key==(*bt)->data.key)
{
*p=*bt;
*flag=1;
}
else if(key<(*bt)->data.key)
search_1(&(*bt)->lchild,key,*bt,p,flag);
else
search_1(&(*bt)->rchild,key,*bt,p,flag);
}
int insert(bitree *bt,elemtype e)
{
bitree p,s;
int flag;
search_1(bt,e.key,NULL,&p,&flag);
if(!flag)
{
s=(bitree)malloc(sizeof(bitnode));
s->data=e;
s->lchild=s->rchild=NULL;
if(!p)
*bt=s;
else if(e.key<p->data.key)
p->lchild=s;
else
p->rchild=s;
return 1;
}
else
return 0;
}
void Delete(bitree *p)
{
bitree q,s;
if(!(*p)->rchild)//右子树空,重接其左子树(待删结点是叶子也走此分支)
{
q=*p;
*p=(*p)->lchild;
free(q);
}
else if(!(*p)->lchild)
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else //左右子树均不空
{
q=*p;
s=(*p)->lchild;//转左然后向右走到尽头(找待删结点的前驱)
while(s->rchild)
{
q=s;
s=s->rchild;
}
(*p)->data=s->data;//s指向被删结点的"前驱"将被删结点前驱的值取代被删结点的值)
if(q!=*p)
q->rchild=s->lchild;//重接*q的右子树
else
q->lchild=s->lchild;//重接*q的左子树
free(s);
}
}
int deletebst(bitree *bt,int key)
{
if(!*bt)
return 0;
else
{
if(key==(*bt)->data.key)
Delete(bt);
else if(key<(*bt)->data.key)
deletebst(&(*bt)->lchild,key);
else
deletebst(&(*bt)->rchild,key);
return 1;
}
}
void InOrderTraverse(bitree bt)
{
if(bt)
{
InOrderTraverse(bt->lchild);
printf("<%d %d> ",bt->data.key,bt->data.others);
InOrderTraverse(bt->rchild);
}
}
int main()
{
bitree bt,p;
int i,j;
elemtype r[10]={{45,1},{12,2},{53,3},{3,4},{37,5},{24,6},{100,7},{61,8},{90,9},{78,10}};
init(&bt);
for(i=0;i<10;i++)
{
insert(&bt,r[i]);
}
InOrderTraverse(bt);
printf("\n\n");
printf("请输入待查找的值:\n");
scanf("%d",&j);
p=search(bt,j);
if(p)
{
printf("表中存在此值");
printf("\n\n");
deletebst(&bt,j);
printf("删除此值之后:\n");
InOrderTraverse(bt);
printf("\n\n");
}
else
printf("表中不存在此值\n");
destroy(&bt);
printf("二叉排序树销毁成功!");
printf("\n\n");
return 0;
}