数据结构--上机实验实验要求:二叉排序树【拓展】

       编写算法实现二叉排序树的创建,插入与删除操作。创建时是根据给定数据的无序序列,按照输入顺序创建

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;
} 


你可能感兴趣的:(数据结构,二叉树)