大二的最后一个作业,等明天再过去答辩完后,我的大二也就基本告一段落。这次的课设没有怎么用心,所以也基本就是应付式的完成的,不过其中还是有挺多东西可以学的,因此就趁着刚写完,认真整理一下,方便以后学习。
接下进入正题
题目要求
利用平衡二叉树实现一个动态查找表
(1) 实现动态查找表的三种基本功能:查找,插入和删除;
(2) 合并两棵平衡二叉树;
(3) 把一棵平衡二叉树分裂成两棵平衡二叉树,使得在一棵树中的所有关键字都小于多等于X,另一棵树中的任一关键字都大于X。
完成说明
课设是基于c/c++语言编写的,开发平台选择的是vc6.0。(汗,我到现在都还只会用vc,当然也用过TC,不过那个古董级的真心用不惯),另外c语言也没学过界面,所以就只能用dos,凑合着看吧。
概要设计
typedef int Status;
typedef int ElemType;
typedef struct BSTNode{
ElemType data;
int bf;
struct BSTNode *lchild ,*rchild;
} BSTNode,* BSTree;
Status SearchBST(BSTree T,ElemType e)//查找
void R_Rotate(BSTree &p)//右旋
void L_Rotate(BSTree &p)//左旋
void LeftBalance(BSTree &T)//插入平衡调整
void RightBalance(BSTree &T)//插入平衡调整
Status InsertAVL(BSTree &T,ElemType e,int &taller)//插入
void DELeftBalance(BSTree &T)//删除平衡调整
void DERightBalance(BSTree &T)//删除平衡调整
Status Delete(BSTree &T,int &shorter)//删除操作
Status DeleteAVL(BSTree &T,ElemType e,int &shorter)//删除操作
void merge(BSTree &T1,BSTree &T2)//合并操作
void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2)//分裂操作
void PrintBSTree(BSTree &T,int lev)//凹入表显示
接下来附上所有源码
#include<stdio.h>
#include<stdlib.h>
//#define TRUE 1
//#define FALSE 0
//#define OK 1
//#define ERROR 0
#define LH +1
#define EH 0
#define RH -1
typedef int Status;
typedef int ElemType;
typedef struct BSTNode{
ElemType data;
int bf;
struct BSTNode *lchild ,*rchild;
} BSTNode,* BSTree;
/*
查找算法
*/
Status SearchBST(BSTree T,ElemType e){
if(!T){
return FALSE; //查找失败
}
else if(e == T->data ){
return TRUE; //查找成功
}
else if (e < T->data){
return SearchBST(T->lchild,e);
}
else{
return SearchBST(T->rchild,e);
}
}
//右旋
void R_Rotate(BSTree &p){
BSTree lc;
lc = p->lchild;
p->lchild = lc->rchild;
lc->rchild = p;
p = lc;
}
//左旋
void L_Rotate(BSTree &p){
BSTree rc;
rc = p->rchild;
p->rchild = rc->lchild;
rc->lchild = p;
p = rc;
}
void LeftBalance(BSTree &T){
BSTree lc,rd;
lc=T->lchild;
switch(lc->bf){
case LH:
T->bf = lc->bf=EH;
R_Rotate(T);
break;
case RH:
rd=lc->rchild;
switch(rd->bf){
case LH: T->bf=RH; lc->bf=EH;
break;
case EH: T->bf=lc->bf=EH;
break;
case RH: T->bf=EH; lc->bf=LH;
break;
}
rd->bf=EH;
L_Rotate(T->lchild);
R_Rotate(T);
}
}
void RightBalance(BSTree &T)
{
BSTree rc,ld;
rc=T->rchild;
switch(rc->bf){
case RH:
T->bf= rc->bf=EH;
L_Rotate(T);
break;
case LH:
ld=rc->lchild;
switch(ld->bf){
case LH: T->bf=RH; rc->bf=EH;
break;
case EH: T->bf=rc->bf=EH;
break;
case RH: T->bf = EH; rc->bf=LH;
break;
}
ld->bf=EH;
R_Rotate(T->rchild);
L_Rotate(T);
}
}
//插入结点
Status InsertAVL(BSTree &T,ElemType e,int &taller){
if(!T){
T= (BSTree) malloc (sizeof(BSTNode));
T->data = e;
T->lchild = T->rchild = NULL;
T->bf = EH;
taller = 1;
}
else{
if(e == T->data){
taller = 0;
return ERROR;
}
if(e < T->data){
if(!InsertAVL(T->lchild,e,taller))
return ERROR;
if(taller)
switch(T->bf){
case LH:
LeftBalance(T);
taller = 0;
break;
case EH:
T->bf = LH;
taller = TRUE;
break;
case RH:
T->bf = EH;
taller = FALSE;
break;
}
}
else{
if (!InsertAVL(T->rchild,e,taller)){
return ERROR;
}
if(taller)
switch(T->bf){
case LH:
T->bf = EH;
taller = FALSE;
break;
case EH:
T->bf = RH;
taller = TRUE;
break;
case RH:
RightBalance(T);
taller = FALSE;
break;
}
}
}
return 1;
}
void DELeftBalance(BSTree &T){
BSTree lc,rd;
lc=T->lchild;
switch(lc->bf){
case LH:
T->bf = EH;
//lc->bf= EH;
R_Rotate(T);
break;
case EH:
T->bf = EH;
lc->bf= EH;
R_Rotate(T);
break;
case RH:
rd=lc->rchild;
switch(rd->bf){
case LH: T->bf=RH; lc->bf=EH;
break;
case EH: T->bf=lc->bf=EH;
break;
case RH: T->bf=EH; lc->bf=LH;
break;
}
rd->bf=EH;
L_Rotate(T->lchild);
R_Rotate(T);
}
}
void DERightBalance(BSTree &T)
{
BSTree rc,ld;
rc=T->rchild;
switch(rc->bf){
case RH:
T->bf= EH;
//rc->bf= EH;
L_Rotate(T);
break;
case EH:
T->bf= EH;
//rc->bf= EH;
L_Rotate(T);
break;
case LH:
ld=rc->lchild;
switch(ld->bf){
case LH: T->bf=RH; rc->bf=EH;
break;
case EH: T->bf=rc->bf=EH;
break;
case RH: T->bf = EH; rc->bf=LH;
break;
}
ld->bf=EH;
R_Rotate(T->rchild);
L_Rotate(T);
}
}
void SDelete(BSTree &T,BSTree &q,BSTree &s,int &shorter){
if(s->rchild){
SDelete(T,s,s->rchild,shorter);
if(shorter)
switch(s->bf){
case EH:
s->bf = LH;
shorter = 0;
break;
case RH:
s->bf = EH;
shorter = 1;
break;
case LH:
DELeftBalance(s);
shorter = 0;
break;
}
return;
}
T->data = s->data;
if(q != T)
q->rchild = s->lchild;
else
q->lchild = s->lchild;
shorter = 1;
}
//删除结点
Status Delete(BSTree &T,int &shorter){
BSTree q;
if(!T->rchild){
q = T;
T = T->lchild;
free(q);
shorter = 1;
}
else if(!T->lchild){
q = T;
T= T->rchild;
free(q);
shorter = 1;
}
else{
SDelete(T,T,T->lchild,shorter);
if(shorter)
switch(T->bf){
case EH:
T->bf = RH;
shorter = 0;
break;
case LH:
T->bf = EH;
shorter = 1;
break;
case RH:
DERightBalance(T);
shorter = 0;
break;
}
}
return TRUE;
}
Status DeleteAVL(BSTree &T,ElemType e,int &shorter){
int sign = 0;
if (!T){
return sign;
}
else{
if(e == T->data){
sign = Delete(T,shorter);
return sign;
}
else if(e < T->data){
sign = DeleteAVL(T->lchild,e,shorter);
if(shorter)
switch(T->bf){
case EH:
T->bf = RH;
shorter = 0;
break;
case LH:
T->bf = EH;
shorter = 1;
break;
case RH:
DERightBalance(T);
shorter = 0;
break;
}
return sign;
}
else{
sign = DeleteAVL(T->rchild,e,shorter);
if(shorter)
switch(T->bf){
case EH:
T->bf = LH;
shorter = 0;
break;
case RH:
T->bf = EH;
break;
case LH:
DELeftBalance(T);
shorter = 0;
break;
}
return sign;
}
}
}
//合并
void merge(BSTree &T1,BSTree &T2){
int taller = 0;
if(!T2)
return;
merge(T1,T2->lchild);
InsertAVL(T1,T2->data,taller);
merge(T1,T2->rchild);
}
void split(BSTree T,ElemType e,BSTree &T1,BSTree &T2){
int taller = 0;
if(!T)
return;
split(T->lchild,e,T1,T2);
if(T->data > e)
InsertAVL(T2,T->data,taller);
else
InsertAVL(T1,T->data,taller);
split(T->rchild,e,T1,T2);
}
//分裂
void splitBSTree(BSTree T,ElemType e,BSTree &T1,BSTree &T2){
BSTree t1 = NULL,t2 = NULL;
split(T,e,t1,t2);
T1 = t1;
T2 = t2;
return;
}
//构建
void CreatBSTree(BSTree &T){
int num,i,e,taller = 0;
printf(“输入结点个数:”);
scanf(“%d”,&num);
printf(“请顺序输入结点值\n”);
for(i = 0 ;i < num;i++){
printf(“第%d个结点的值”,i+1);
scanf(“%d”,&e);
InsertAVL(T,e,taller) ;
}
printf(“构建成功,输入任意字符返回\n”);
getchar();
getchar();
}
//凹入表形式显示方法
void PrintBSTree(BSTree &T,int lev){
int i;
if(T->rchild)
PrintBSTree(T->rchild,lev+1);
for(i = 0;i < lev;i++)
printf(” “);
printf(“%d\n”,T->data);
if(T->lchild)
PrintBSTree(T->lchild,lev+1);
}
void Start(BSTree &T1,BSTree &T2){
int cho,taller,e,k;
taller = 0;
k = 0;
while(1){
system(“cls”);
printf(” 平衡二叉树操作的演示 \n\n”);
printf(“******************************************************************************\n”);
printf(” 平衡二叉树显示区 \n”);
printf(“T1树\n”);
if(!T1 )
printf(“\n 当前为空树\n”);
else{
PrintBSTree(T1,1);
}
printf(“T2树\n”);
if(!T2 )
printf(“\n 当前为空树\n”);
else
PrintBSTree(T2,1);
printf(“\n******************************************************************************\n”);
printf(“T1操作:1.创建 2.插入 3.查找 4.删除 10.分裂\n”);
printf(“T2操作:5.创建 6.插入 7.查找 8.删除 11.分裂\n”);
printf(” 9.合并T1,T2 0.退出\n”);
printf(“******************************************************************************\n”);
printf(“输入你要进行的操作:”);
scanf(“%d”,&cho);
switch(cho){
case 1:
CreatBSTree(T1);
break;
case 2:
printf(“请输入要插入关键字的值”);
scanf(“%d”,&e);
InsertAVL(T1,e,taller) ;
break;
case 3:
printf(“请输入要查找关键字的值”);
scanf(“%d”,&e);
if(SearchBST(T1,e))
printf(“查找成功!\n”);
else
printf(“查找失败!\n”);
printf(“按任意键返回87”);
getchar();
getchar();
break;
case 4:
printf(“请输入要删除关键字的值”);
scanf(“%d”,&e);
if(DeleteAVL(T1,e,k))
printf(“删除成功!\n”);
else
printf(“删除失败!\n”);
printf(“按任意键返回”);
getchar();
getchar();
break;
case 5:
CreatBSTree(T2);
break;
case 6:
printf(“请输入要插入关键字的值”);
scanf(“%d”,&e);
InsertAVL(T2,e,taller) ;
break;
case 7:
printf(“请输入要查找关键字的值”);
scanf(“%d”,&e);
if(SearchBST(T2,e))
printf(“查找成功!\n”);
else
printf(“查找失败!\n”);
printf(“按任意键返回”);
getchar();
getchar();
break;
case 8:
printf(“请输入要删除关键字的值”);
scanf(“%d”,&e);
if(DeleteAVL(T2,e,k))
printf(“删除成功!\n”);
else
printf(“删除失败!\n”);
printf(“按任意键返回”);
getchar();
getchar();
break;
case 9:
merge(T1,T2);
T2 = NULL;
printf(“合并成功,按任意键返回”);
getchar();
getchar();
break;
case 10:
printf(“请输入要中间值字的值”);
scanf(“%d”,&e);
splitBSTree(T1,e,T1,T2) ;
printf(“分裂成功,按任意键返回”);
getchar();
getchar();
break;
case 11:
printf(“请输入要中间值字的值”);
scanf(“%d”,&e);
splitBSTree(T2,e,T1,T2) ;
printf(“分裂成功,按任意键返回”);
getchar();
getchar();
break;
case 0:
system(“cls”);
exit(0);
}
}
}
void main(){
BSTree T1 = NULL;
BSTree T2 = NULL;
Start(T1,T2);
}
最后附上一个运行图吧,创建后的一棵平衡二叉树