二叉排序树(BinarySortTree):
具有下列性质的二叉树:
(1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(2)若右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(3)左、右子树也分别为二叉排序树;
#include<iostream>
#include<stdio.h>
using namespace std;
typedef struct node //记录类型
{
int key; //关键字项
struct node *lchild,*rchild; //左右孩子指针
} BSTNode,*BSTree;
void InsertBST(BSTree *t,int k)
{
BSTNode *f,*p=*t;
while(p)
{
if(p->key==k) return;//去掉重复的元素
f=p;
p=(k<p->key)?p->lchild:p->rchild;
}
p=(BSTree)malloc(sizeof(BSTNode));
p->key=k;
p->lchild=p->rchild=NULL;
if(*t==NULL) *t=p;
else if (k<f->key) f->lchild=p;
else f->rchild=p;
}
BSTree SearchBST(BSTree t, int k)
{
BSTree p;
p=t;
while((p!=NULL)&&(p->key!=k))
if(k<p->key) p=p->lchild;
else p=p->rchild;
return(p);
}
BSTree InsertBST2(BSTree t,int k)//插入关键字k,非递归
{
//若二叉排序树 t 中没有关键字k,则插入,否则直接返回
BSTree p=t;//p的初值指向根结点
BSTree f;//f保存当前查找的结点
while(p)//查找插入位置,插入位置一定是一个叶子结点
{
if(p->key==k)//树中已有k,无需插入
{
cout<<"树中存在"<<k<<",插入失败"<<endl;
return t;
}
f=p;
//若k<p->key,在左子树上查找,否则在右子树上查找
p=(k<p->key)?p->lchild:p->rchild;
}
p=(BSTree)malloc(sizeof(BSTNode));
p->key=k;
p->lchild=p->rchild=NULL;
if(t==NULL)t=p;//插入结点为新的根结点
else if(k<f->key)f->lchild = p;//插入结点为左孩子
else f->rchild = p;//插入结点为右孩子
return t;
}
void DelBST(BSTree *t,int k)
{
/*在二叉排序树*t中删除关键字为k的结点*/
BSTree p,f,q,s,root;
root=*t;
p=*t; f=NULL;
while(p)
{if(p->key==k) break; /*找到关键字为k的结点*/
f=p;
p=(k<p->key)?p->lchild:p->rchild;
/* 分别在*p的左、右子树中查找*/
}
if(!p) return; /*二叉排序树中无关键字为k的结点*/
if(p->lchild==NULL&&p->rchild==NULL)
{if(p==*t) *t=NULL;
else if(p==f->lchild) f->lchild=NULL;
else f->rchild=NULL;
free(p);
}
else
if(p->lchild==NULL&&p->rchild!=NULL) /* *p无左子树*/
{ if(f->lchild==p)
f->lchild=p->rchild; /*将*p的右子树链接到其父结点的左链上*/
else
f->rchild=p->rchild; /*将*p的右子树链接到其父结点的右链上*/
free(p);
}
else if(p->rchild==NULL&&p->lchild!=NULL) /**p有左子树*/
{ if (f->lchild==p) /*用*p的左子树代替*p*/
f->lchild=p->lchild;
else
f->rchild=p->lchild;
free(p);
}
else if(p->lchild!=NULL&&p->rchild!=NULL)
{q=p;s=p->lchild;
while(s->rchild) {q=s;s=s->rchild;}
p->key=s->key;
if(q!=p) q->rchild=s->lchild;
else q->lchild=s->lchild;
free(s);
}
}
void InorderBSTree(BSTree p)
{
if(p)
{
InorderBSTree(p->lchild);
printf("%d ",p->key);
InorderBSTree(p->rchild);}
}
void operation()
{
cout<<"\t0,操作结束"<<endl;
cout<<"\t1,初始化一棵二叉排序树"<<endl;
cout<<"\t2,在二叉排序树上查找一个元素"<<endl;
cout<<"\t3,在二叉排序树上插入一个元素"<<endl;
cout<<"\t4,在二叉排序树上删除一个元素"<<endl;
cout<<"\t5,中序遍历二叉排序树"<<endl;
}
int main()
{
BSTree t=NULL,p;
int k,key;
operation();
while(true)
{
printf("\t请输入操作序号:\n");
scanf("%d",&k);
switch(k)
{
case 0: exit(0);
case 1: printf("请输入关键字的值,以0结束:\n");
scanf("%d",&key);
while(key)
{
InsertBST(&t,key);
scanf("%d",&key);
}
printf("二叉排序树建立完成:\n");
break;
case 2: printf("请输入要查找的结点的关键字的值:\n");
scanf("%d",&key);
p=SearchBST(t,key);
if(p==NULL) printf("没有查找到该结点\n");
else printf("查找到该结点\n");
break;
case 3: printf("请输入插入元素的值:\n");
scanf("%d",&key);
InsertBST2(t,key);
printf("该点插入成功\n");
break;
case 4: printf("请输入要删除的结点的关键字的值:\n");
scanf("%d",&key);
DelBST(&t,key);
printf("该点删除成功\n");
break;
case 5: printf("中序遍历建立的二叉排序树的序列为:\n");
InorderBSTree(t);
break;
default:printf("你没有选择排序方式");break;
}
}
return 0;
}