#include<stdio.h>
#include<stdlib.h>
typedef int datatype;
typedef struct node//二叉排序树结点定义
{
datatype key;//结点值
struct node *lchild,*rchild;//左右孩子指针
}bsnode;
typedef bsnode *bstree;
//二叉排序树的插入
void insertbstree(bstree *t,datatype x)
{
bstree f,p;
p=*t;
while(p)//查找插入位置
{
if(x==p->key)
return;//若二叉排序树t中已有key,则无需插入
f=p;//f用于保存新结点的最终插入位置
p=(x<p->key)?p->lchild:p->rchild;
}
p=(bstree)malloc(sizeof(bsnode));//生成待插入的新节点
p->key=x;
p->lchild=p->rchild=NULL;
if(*t==NULL)
*t=p;//原数为空
else
if(x<f->key)
f->lchild=p;
else
f->rchild=p;
}
//根据输入的结点序列,建立一颗二叉排序树,并返回根节点的地址
bstree creatbstree(void)
{
bstree t=NULL;
datatype key;
printf("\n请输入一个以-1未结束标志的结点序列:\n");
scanf("%d",&key);//输入一个关键字
while(key!=-1)
{
insertbstree(&t,key);//将key插入二叉排序树t
scanf("%d",&key);
}
return t;//返回建立的二叉排序树的根指针
}
//二叉排序树的非递归查找
void bssearch1(bstree t,datatype x,bstree *p,bstree *q)
{
//q返回待查结点x在二叉排序树的地址,p返回待查结点x的父节点地址
*p=NULL;
*q=t;
while(*q)
{
if(x==(*q)->key)
return;
*p=*q;
*q=(x<(*q)->key)?(*q)->lchild:(*q)->rchild;
}
return;
}
//二叉排序树的递归查找
bstree bssearch2(bstree t,datatype x)
{
//在二叉排序树t中查找关键字为x的结点
if(t==NULL||x==t->key)
return t;
if(x<t->key)
return bssearch2(t->lchild,x);//递归的在左子树中检索
else
return bssearch2(t->rchild,x);//递归的在右子树中检索
}
//在二叉排序树t中删除结点值为x的结点
bstree delbstree(bstree t,datatype x)
{
bstree p,q,child;
bssearch1(t,x,&p,&q);//查找被删节点
if(q)//找到了待删除节点
{
if(q->lchild==NULL&&q->rchild==NULL)//被删节点为叶子结点
{
if(p)//待删除节点有双亲
{
if(p->lchild==q)
p->lchild=NULL;
else
p->rchild=NULL;
}
else
t=NULL;//被删结点为树根
free(q);
}
else
if(q->lchild==NULL)//被删结点左子树为空,用其右子树代替
{
if(p)//被删结点的双亲结点不为空
{
if(p->lchild==q)
p->lchild=q->rchild;//q是其双亲结点的左孩子
else
p->rchild=q->rchild;//q是其双亲节点的右孩子
}
else
t=q->rchild;
free(q);
}
else
if(q->rchild==NULL)
{
if(p)//被删结点的双亲结点不为空
{
if(p->lchild==q)
p->lchild=q->lchild;
else
p->lchild=q->lchild;
}
else
t=q->lchild;
free(q);
}
else//被删结点的左右子树均不为空,用右子树代替被删结点
{
child=q->rchild;
while(child->lchild)
child=child->lchild;
child->lchild=q->lchild;
if(p)
{
if(p->lchild==q)
p->lchild=q->rchild;
else
p->rchild=q->rchild;
}
else
t=q->rchild;
free(q);
}
}
return t;
}
//中序遍历二叉排序树
void inorder(bstree t)
{
if(t)
{
inorder(t->lchild);
printf("%4d",t->key);
inorder(t->rchild);
}
}
int main()
{
bstree p,q;
datatype x;
bstree t;
t=creatbstree();//创建二叉排序树
inorder(t);
printf("\n请输入一个待查找的结点值:\n");
scanf("%d",&x);
bssearch1(t,x,&p,&q);
if(q)
printf("\nFOUND!");
else
printf("\nNOT FOUND!");
printf("\n请输入一个待插入的结点值:\n");
scanf("%d",&x);
insertbstree(&t,x);
inorder(t);
printf("\n请输入一个待删除的结点值:\n");
scanf("%d",&x);
t=delbstree(t,x);//删除指定结点
inorder(t);
}
#include<stdlib.h>
typedef int datatype;
typedef struct node//二叉排序树结点定义
{
datatype key;//结点值
struct node *lchild,*rchild;//左右孩子指针
}bsnode;
typedef bsnode *bstree;
//二叉排序树的插入
void insertbstree(bstree *t,datatype x)
{
bstree f,p;
p=*t;
while(p)//查找插入位置
{
if(x==p->key)
return;//若二叉排序树t中已有key,则无需插入
f=p;//f用于保存新结点的最终插入位置
p=(x<p->key)?p->lchild:p->rchild;
}
p=(bstree)malloc(sizeof(bsnode));//生成待插入的新节点
p->key=x;
p->lchild=p->rchild=NULL;
if(*t==NULL)
*t=p;//原数为空
else
if(x<f->key)
f->lchild=p;
else
f->rchild=p;
}
//根据输入的结点序列,建立一颗二叉排序树,并返回根节点的地址
bstree creatbstree(void)
{
bstree t=NULL;
datatype key;
printf("\n请输入一个以-1未结束标志的结点序列:\n");
scanf("%d",&key);//输入一个关键字
while(key!=-1)
{
insertbstree(&t,key);//将key插入二叉排序树t
scanf("%d",&key);
}
return t;//返回建立的二叉排序树的根指针
}
//二叉排序树的非递归查找
void bssearch1(bstree t,datatype x,bstree *p,bstree *q)
{
//q返回待查结点x在二叉排序树的地址,p返回待查结点x的父节点地址
*p=NULL;
*q=t;
while(*q)
{
if(x==(*q)->key)
return;
*p=*q;
*q=(x<(*q)->key)?(*q)->lchild:(*q)->rchild;
}
return;
}
//二叉排序树的递归查找
bstree bssearch2(bstree t,datatype x)
{
//在二叉排序树t中查找关键字为x的结点
if(t==NULL||x==t->key)
return t;
if(x<t->key)
return bssearch2(t->lchild,x);//递归的在左子树中检索
else
return bssearch2(t->rchild,x);//递归的在右子树中检索
}
//在二叉排序树t中删除结点值为x的结点
bstree delbstree(bstree t,datatype x)
{
bstree p,q,child;
bssearch1(t,x,&p,&q);//查找被删节点
if(q)//找到了待删除节点
{
if(q->lchild==NULL&&q->rchild==NULL)//被删节点为叶子结点
{
if(p)//待删除节点有双亲
{
if(p->lchild==q)
p->lchild=NULL;
else
p->rchild=NULL;
}
else
t=NULL;//被删结点为树根
free(q);
}
else
if(q->lchild==NULL)//被删结点左子树为空,用其右子树代替
{
if(p)//被删结点的双亲结点不为空
{
if(p->lchild==q)
p->lchild=q->rchild;//q是其双亲结点的左孩子
else
p->rchild=q->rchild;//q是其双亲节点的右孩子
}
else
t=q->rchild;
free(q);
}
else
if(q->rchild==NULL)
{
if(p)//被删结点的双亲结点不为空
{
if(p->lchild==q)
p->lchild=q->lchild;
else
p->lchild=q->lchild;
}
else
t=q->lchild;
free(q);
}
else//被删结点的左右子树均不为空,用右子树代替被删结点
{
child=q->rchild;
while(child->lchild)
child=child->lchild;
child->lchild=q->lchild;
if(p)
{
if(p->lchild==q)
p->lchild=q->rchild;
else
p->rchild=q->rchild;
}
else
t=q->rchild;
free(q);
}
}
return t;
}
//中序遍历二叉排序树
void inorder(bstree t)
{
if(t)
{
inorder(t->lchild);
printf("%4d",t->key);
inorder(t->rchild);
}
}
int main()
{
bstree p,q;
datatype x;
bstree t;
t=creatbstree();//创建二叉排序树
inorder(t);
printf("\n请输入一个待查找的结点值:\n");
scanf("%d",&x);
bssearch1(t,x,&p,&q);
if(q)
printf("\nFOUND!");
else
printf("\nNOT FOUND!");
printf("\n请输入一个待插入的结点值:\n");
scanf("%d",&x);
insertbstree(&t,x);
inorder(t);
printf("\n请输入一个待删除的结点值:\n");
scanf("%d",&x);
t=delbstree(t,x);//删除指定结点
inorder(t);
}