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