某某工业大学应数刘智煌数据结构.docx
《某某工业大学应数刘智煌数据结构.docx》由会员分享,可在线阅读,更多相关《某某工业大学应数刘智煌数据结构.docx(17页珍藏版)》请在冰豆网上搜索。
某某工业大学应数刘智煌数据结构
某某
课程设计
课程名称数据结构课程设计
题目名称二叉排序树的实现
学生学院应用数学学院
专业班级
学号
学生姓名
指导教师刘大哥
2016年.平台VC++6.0
问题
二叉排序树的实现
二叉排序补充概念(也可以参考书上第九章第二节)
左子树的数据总是大于根和右子树的数据,这种就叫做二叉排序树,简单一点,二叉树左边的数据大于右边.
1)编程实现二叉排序树,包括生成、插入,删除;
2)对二叉排序树进行先根、中根、和后根非递归遍历;
3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。
4)分别用二叉排序树和数组去存储一个班(50人以上)的成员信息(至少包括学号、姓名、成绩3项),对比查找效率,并说明在什么情况下二叉排序树效率高,为什么?
5)格式就要按照我们作业的要求,对数据测试,分析,总结和改进的工作要做的详细一点
代码实现
#include
#include
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineOVERFLOW-1
typedefintStatus;
typedefintStudentITREE1ype;
#defineN100
#defineSIZE100
#defineINC100
#defineEQ(a,b)((a)==(b))
#defineLT(a,b)((a)<(b))
#defineLQ(a,b)((a)<=(b))
//二叉树节点
structElemType//构造对象类型
{
StudentITREE1ypekey;//定义学号
charname[10];//定义名字字符串
intscore;
};
typedefstructBiTNode//定义数据类型
{
ElemTypedata;
structBiTNode*lchild,*rchild;//左右孩子指针
}*BiTree,BiTNode;
//堆栈
typedefstruct
{
BiTree*base;//栈底
BiTree*top;
intsize;//大小
}SqStack;
StatusInitStack(SqStack&S)
{
S.base=(BiTree*)malloc(SIZE*sizeof(BiTree))//申请一个空间储存树;
if(!
S.base)exit(OVERFLOW);//栈底不存在退出程序
S.top=S.base;//把顶指针值赋给底指针
S.size=SIZE;//树的大小等于申请SizE大小
return1;
}
StatusGetTop(SqStackS,BiTree&e)//获得最上面的指针
{
if(S.top==S.base)return0;//头等于尾空指针
e=*(S.top-1);
return1;
}
StatusPush(SqStack&S,BiTreee)//把输入的数压进栈
{
if(S.top-S.base>=S.size)//有空间可以储存
{
S.base=(BiTree*)realloc(S.base,(S.size+INC)*sizeof(BiTree));//有空间就把输入的数推进栈里,没有就退出程序。
if(!
S.base)exit(OVERFLOW);
S.top=S.base+S.size;
S.size+=INC;
}
*S.top++=e;
return1;
}
StatusPop(SqStack&S,BiTree&e)//把数推出指针
{
if(S.top==S.base)return0;//
e=*--S.top;//把不需要的数推出
return1;
}
intStackEmpty(SqStackS)//测试是不是空栈
{
if(S.base==S.top)return1;
elsereturn0;
}
//队列
typedefBiTreeQElemType;//构造一个树
typedefstructQNode
{
QElemTypedata;
QNode*next;//*next指针
}*QueuePtr;
structLinkQueue//构造一个队列
{
QueuePtrfront,rear;
};
StatusInitQueue(LinkQueue&Q)//队列类型
{
if(!
(Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode))))exit(OVERFLOW);//如果首队列尾队列队列,申请空间储存结点,结束程序
Q.front->next=NULL;
return1;
}
StatusEnQueue(LinkQueue&Q,QElemTypee)
{
QueuePtrp;
if(!
(p=(QueuePtr)malloc(sizeof(QNode))))exit(OVERFLOW);
p->data=e;
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
return1;
}
StatusDeQueue(LinkQueue&Q,QElemType&e)
{
QueuePtrp;
if(Q.front==Q.rear)return0;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
return1;
}
//二叉排序树
StatusInitDSTable(BiTree&TREE1)//构造一棵树叫TREE1
{
TREE1=NULL;
return1;
}
BiTreeSearchBST(BiTreeT,StudentITREE1ypekey)//查找树里面的学号
{
if(!
T||EQ(key,T->data.key))//比较输入的学号和树里面的学号
returnT;
elseifLT(key,T->data.key)
returnSearchBST(T->lchild,key);//如果相同返回树
else
returnSearchBST(T->rchild,key);}
StatusSearchBST(BiTree&T,StudentITREE1ypekey,BiTreef,BiTree&p)
{
if(!
T)
{
p=f;
return0;
}//如果非空,把f的值赋给p
}
elseifEQ(key,T->data.key)
{
p=T;
return1;
}
elseifLT(key,T->data.key)
returnSearchBST(T->lchild,key,T,p);
else
returnSearchBST(T->rchild,key,T,p);
}//不同就重复查找直到相同
StatusInsertBST(BiTree&T,ElemTypee)//插入结点信息
{
BiTreep,s;
if(!
SearchBST(T,e.key,NULL,p))
{
s=(BiTree)malloc(sizeof(BiTNode));
s->data=e;//插入结点
s->lchild=s->rchild=NULL;//左右孩子指针等于空值
if(!
p)
T=s;//若果非空树,s的值赋给T。
elseifLT(e.key,p->data.key)
p->lchild=s;
else
p->rchild=s;
return1;
}//如果e.key大于data.key,则插入左孩子指针,否则插入右孩子指针
else
return0;
}
//删除树
voidDelete(BiTree&p)
{
BiTreeq,s;
if(!
p->rchild)
{
q=p;
p=p->lchild;
free(q);
}//如果,右孩子没有p,则在左孩子找p
elseif(!
p->lchild)
{
q=p;
p=p->rchild;
free(q);
}//如果左孩子没有p,则在右孩子中找。
else
{
q=p;
s=p->lchild;//把左孩子中p赋给s。
while(s->rchild)
{
q=s;
s=s->rchild;
}//循环直到右孩子不存在s。
p->data=s->data;//把找到最后一个右孩子的值赋给p
//整段把树左边移到右边。
if(q!
=p)//如果q不等于p
q->rchild=s->lchild;//右孩子树移到左边
else
q->lchild=s->lchild;//否则s的值赋给q
free(s);
}
}
StatusDeleteBST(BiTree&T,StudentITREE1ypekey)//删除树
{
if(!
T)
return0;
else
{
ifEQ(key,T->data.key)
Delete(T);
elseifLT(key,T->data.key)
DeleteBST(T->lchild,key);
else
DeleteBST(T->rchild,key);
return1;
}
}//循环找和删除。
intBiTreeDepth(BiTreeT)//树的深度
{
inti,j;
if(!
T)return0;
if(T->lchild)
i=BiTreeDepth(T->lchild);
elsei=0;
if(T->rchild)
j=BiTreeDepth(T->rchild);
elsej=0;
returni>j?
i+1:
j+1;
}//若左孩子存在,循环寻找直到左孩子不存在,找到树的深度,返回树的深度。
voidVisit(ElemTypee)//查看结点中学号
{
printf("%d->",e.key);
}
//中序遍历
StatusInOrderTraverse(BiTreeT)
{
BiTreep;
SqStackS;
InitStack(S);Push(S,T);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)Push(S,p->lchild);
Pop(S,p);
if(!
StackEmpty(S))
{
Pop(S,p);
Visit(p->data);
Push(S,p->rchild);
}
}
printf("\n");
return1;
}
//前序遍历
StatusPreOrderTraverse(BiTreeT)
{
BiTreep;
SqStackS;
InitStack(S);Push(S,T);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)
{
Push(S,p->lchild);
Visit(p->data);
}
Pop(S,p);
if(!
StackEmpty(S))
{
Pop(S,p);
Push(S,p->rchild);
}
}
printf("\n");
return1;
}
//后序遍历
StatusPostOrderTraverse(BiTreeT)
{
SqStackS;SqStackR;
BiTreep;BiTreer;InitStack(S);InitStack(R);
Push(S,T);
while(!
StackEmpty(S))
{
while(GetTop(S,p)&&p)Push(S,p->lchild);
Pop(S,p);
if(!
StackEmpty(S))
{
if(!
StackEmpty(R))GetTop(R,r);
if(GetTop(S,p)&&p->rchild&&p!
=r)
{
Push(S,p->rchild);Push(R,p);
}
else
{
Pop(S,p);Visit(p->data);
if(r==p)Pop(R,r);
p=NULL;Push(S,p);
}
}
}
printf("\n");
return1;
}
voidShowTree(BiTreeT)//层次遍历法显示树
{
LinkQueueq;
BiTrees;
intd,t,i,n,num;
d=t=i=n=0;
num=1;
d=BiTreeDepth(T);
if(T)
{
InitQueue(q);
EnQueue(q,T);
while(num<=(pow(2,d)-1))
{
if(num==pow(2,i))
{
printf("\n");
i++;
t=0;
}
n=(int)pow(2,d-i+t);
for(intx=1;x<=n-1;x++)printf("");
t=1;
DeQueue(q,s);
if(s==NULL){printf("");num++;}
else{printf("%d",s->data.key);num++;}
if(s&&s->lchild)EnQueue(q,s->lchild);
elseEnQueue(q,NULL);
if(s&&s->rchild)EnQueue(q,s->rchild);
elseEnQueue(q,NULL);
}
}
printf("\n");
}
intShowTree2(BiTreeT,intn)//递归法显示树
{
inti;
if(T==NULL)return1;
ShowTree2(T->rchild,n+1);
for(i=0;iprintf("%d\n",T->data.key);
ShowTree2(T->lchild,n+1);
}
intmain()
{
BiTreeTREE1,p=NULL;
StudentITREE1ypekey;charname[10];intscore;ElemTypee;
printf("[1]:
BuildtheBinarySortTree[2]:
InserttheNodes[3]:
DeleteNodes[4]:
preOrderTraverse,InOrderTraverse,postOrderTraverse[5]:
build50Nodesandtesttheefficiency\n");
while(true){
charchoise;scanf("%c",&choise);
if(choise=='q')break;
switch(choise){
case'[1]':
InitDSTable(TREE1);
printf("\n\n\n\PleaseinsertthenumberoftheNodesyouwant:
(x)");
intN1;scanf("%d",&N1);
printf("pleaseinsert:
\n\nKeyStudent’snamescore\n")
for(inti=0;i<=N1-1;i++)
{
scanf("%d%s%d",&e.key,e.name,&e.score);
InsertBST(TREE1,e);
}
printf("thebinarytreeisshownasfollow:
\n\n");
ShowTree(TREE1);
break;
case'[2]':
printf("pleasetypeintheDataas:
\n\nStudentIDStudent’sNameStudent’sscore\n");
scanf("%d%s%d",&e.key,e.name,&e.score);
p=SearchBST(TREE1,e.key);
if(p)
printf("youcannotrepeattheKey\n");
else{
InsertBST(TREE1,e);
ShowTree(TREE1);
}
break;
case'c':
printf("PleaseinserttheS:
");
intN2;scanf("%d",&N2);
p=SearchBST(TREE1,N2);
if(p){
printf("Deleted:
\nTheNUMBERSyouhavedeleteisasbelow\n")
printf("%d%s%d\n",p->data.key,p->data.name,p->data.score);
DeleteBST(TREE1,N2);
ShowTree(TREE1);
}
break;
case'[3]':
printf("PreOrderTraverse:
\n");
PreOrderTraverse(TREE1);
printf("InOrderTraverse:
\n");
InOrderTraverse(TREE1);
printf(":
PostOrderTraverse\n");
PostOrderTraverse(TREE1);
break;
case'e':
InitDSTable(TREE1);
structElemTyper[N]={{43,"name",43},{25,"name",35},{48,"name",48},{1,"name6",82},
{24,"name",32},{9,"name",85},{38,"name",36},{28,"name",36},{27,"name",37},
{23,"name",33},{12,"name",12},{40,"name",38},{13,"name",13},{45,"name",14},
{29,"name",39},{35,"name",35},{21,"name",31},{30,"name",38},{20,"name",20},
{11,"name",11},{31,"name",31},{19,"name",19},{32,"name",32},{18,"name",18},
{47,"name",14},{8,"name4",80},{5,"name8",84},{4,"name2",78},{17,"name",17},
{49,"name",14},{34,"name",32},{16,"name",16},{15,"name",15},{3,"name7",83},
{41,"name",14},{36,"name",34},{14,"name",14},{2,"name1",4},{26,"name",34},
{7,"name9",85},{39,"name",39},{46,"name",46},{10,"name5",81},{22,"name",30},
{42,"name",44},{33,"name",33},{44,"name",44},{6,"name3",79},{37,"name",37},
{50,"name",50}};
for(inti=0;i{
InsertBST(TREE1,r[i]);
}
intn=10000000;//总共查找次数
doublestart=clock();//查找二叉排序树开始时间
for(inti=0;isrand(i);//随循环设置随机种子
intrandnumber=rand()%50;//每一次给定一个0到50的随机数
p=SearchBST(TREE1,randnumber);
//if(p)
//printf("%d%s%d\n",p->data.key,p->data.name,p->data.score);
}
doublefinish=clock();//查找二叉排序树结束时间
doubletime=finish-start;
printf("在二叉排序树里随机查找任意一个关键字%d次所需时间为:
%lf",n,time);
start=clock();//查找数组开始时间
for(inti=0;isrand(i);//随循环设置随机种子
intrandnumber=rand()%50;//每一次给定一个0到50的随机数