数据结构-二叉排序树

二叉排序树(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;
}


 

发布了32 篇原创文章 · 获赞 5 · 访问量 16万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章