數據結構-二叉排序樹

二叉排序樹(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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章