编写算法实现二叉排序树的创建,插入与删除操作。(创建时是根据给定数据的无序序列,按照输入顺序创建)
1.二叉排序树的概念:
二叉排序树是一种动态树表。
二叉排序树的定义:二叉排序树或者是一棵空树,
或者是一棵具有如下性质的二叉树:
⑴ 若它的左子树非空,则左子树上所有结点的值均小于根结点的值;
⑵ 若它的右子树非空,则右子树上所有结点的值均大于根结点的值;
⑶ 左、右子树本身又各是一棵二叉排序树。二叉排序树的性质: 按中序遍历二叉排序树,所得到的中序遍历序列是一个递增有序序列
2.二叉排序树的插入:
在二叉排序树中插入新结点,要保证插入后的二叉树仍符合二叉排序树的定义。
插入过程:若二叉排序树为空,则待插入结点*S作为根结点插入到空树中;
当非空时,将待插结点关键字S->key和树根关键字t->key进行比较,
若s->key = t->key,则无须插入,若s->key< t->key,则插入到根的左子树中,
若s->key> t->key,则插入到根的右子树中。而子树中的插入过程和在树中的插入过程相同,
如此进行下去,直到把结点*s作为一个新的树叶插入到二叉排序树中,或者直到发现树已有相同关键字的结点为止。
3. 二叉排序树生成:
从空的二叉排序树开始,经过一系列的查找插入操作以后,生成了一棵二叉排序树。
说明:
① 每次插入的新结点都是二叉排序树上新的叶子结点。
② 由不同顺序的关键字序列,会得到不同二叉排序树。
③ 对于一个任意的关键字序列构造一棵二叉排序树,其实质上对关键字进行排序。
4.二叉排序树的删除:
删除有4种方法这里介绍一种(如算法),根据中序遍历找到后件,在二叉排序树上的体现为找到删除节点先向右转。然后找到右子树上最左端节 点,将其替换。
删除节点有多种情况:
1.没有左节点。
2.没有右节点。
3.左右节点都有。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef struct node
{
int key;
struct node *l,*r;
}bstnode;
int bstinsert(bstnode *&p,int k)
{
if(p==NULL)
{
p=new bstnode();
p->key=k;
p->l=p->r=NULL;
return 1;
}
else if(k==p->key)//此处去重
return 0;
else if(k<p->key)
return bstinsert(p->l,k);
else
return bstinsert(p->r,k);
}
void deletebst(bstnode *&p,int k)//使用查找后件的方法 就是再找到删除点之后二叉树先向右转一次再找到最左端节点
{
bstnode *oo;
bstnode *t,*uu;
t=p;
uu=NULL;
while(t)
{
if(t->key==k)
break;
uu=t;
if(t->key<k)
t=t->r;
else
t=t->l;
}
if(!t)
{
printf("未找到删除项\n");
return;
}
else
{
if((t->l)&&(t->r))
{
bstnode *pp;
pp=t;
bstnode *ss;
ss=t->r;
while(ss->l)//ss以表示被用来替换的点
{
pp=ss;//pp表示用来替换的点的父节点
ss=ss->l;
}
t->key=ss->key;
if(t!=pp)
{
pp->l=ss->r;
}
else
pp->r=ss->r;
free(ss);
return ;
}
else if(!t->l)
{
oo=t;
t=t->r;
}
else if(!t->r)
{
oo=t;
t=t->l;
}
if(!uu)
p=t;
else if(oo==uu->r)
uu->r=t;
else if(oo==uu->l)
uu->l=t;
free(oo);
}
}
void build(bstnode *&bt,int *str,int n)
{
bt=NULL;
for(int i=0;i<=n-1;i++)
{
bstinsert(bt,str[i]);//每次都应该从树头开始
}
}
void preorder(bstnode *bt)
{
if(bt!=NULL)
{
printf("%d ",bt->key);
preorder(bt->l);
preorder(bt->r);
}
}
void inorder(bstnode *bt)
{
if(bt!=NULL)
{
inorder(bt->l);
printf("%d ",bt->key);
inorder(bt->r);
}
}
void posorder(bstnode *bt)
{
if(bt!=NULL)
{
posorder(bt->l);
posorder(bt->r);
printf("%d ",bt->key);
}
}
int main()
{
int n;
int num[10120];
while(1)
{
printf("请输入一个整数:");
scanf("%d",&n);
printf("请输入%d个整数(用空格隔开):",n);
for(int i=0;i<n;i++)
{
scanf("%d",&num[i]);
}
bstnode *nd=new bstnode();
build(nd,num,n);
printf("************前序遍历************\n");
preorder(nd);
printf("\n");
printf("************中序遍历************\n");
inorder(nd);
printf("\n");
printf("************后序遍历************\n");
posorder(nd);
printf("\n");
printf("请输入所要插入数据的个数:");
int yy;
scanf("%d",&yy);
for(int i=0;i<yy;i++)
{
int aa;
printf("输入插入项:");
scanf("%d",&aa);
bstinsert(nd,aa);
printf("************中序遍历************\n");
inorder(nd);
printf("\n");
}
printf("请输入所要删除数据的个数:");
int yy1;
scanf("%d",&yy1);
for(int i=0;i<yy1;i++)
{
int cc;
printf("输入删除项:");
scanf("%d",&cc);
deletebst(nd,cc);
printf("************中序遍历************\n");
inorder(nd);
printf("\n");
}
}
return 0;
}