数据结构实验指导书.docx
《数据结构实验指导书.docx》由会员分享,可在线阅读,更多相关《数据结构实验指导书.docx(34页珍藏版)》请在冰豆网上搜索。
数据结构实验指导书
实验一顺序表操作
实验二栈和队列
实验三栈
实验四二叉树的操作
实验五图的遍历操作
实验六数据查找
实验七哈希表设计
实验八排序
实验一顺序表操作
一、实验目的
1.熟悉C语言的上机环境,掌握C语言的基本结构。
2.会定义线性表的顺序存储结构。
3.熟悉对顺序表的一些基本操作和具体的函数定义。
二、实验要求
1.认真阅读和掌握本实验内容所给的全部程序。
2.保存和打印出程序运行结果,并结合程序进行分析。
注意事项
在做第一次“数据结构”课程实验之前,要在硬盘(e:
\)上建立好自己的工作目录,专门来存储你所做的实验程序及相关信息,以后每次做实验都采用这个目录。
三、实验内容
a.以输入整形数据为主,输入后按“?
”结束输入。
b.程序所能表达到的功能为:
实现顺序表的创建、查找、插入、删除等功能。
c.程序运行后,输入数据并执行。
#include"stdio.h"
#include"conio.h"
#defineMaxSize50
typedefcharelemtype;
typedefstructnode
{
elemtypedata[MaxSize];
intlen;
}lnode,*List;
voidinit(ListL)
{L->len=0;}
intlength(ListL)
{returnL->len;}
elemtypegetnode(ListL,intpos)
{
if(pos<1||pos>L->len)printf("error");
elsereturnL->data[pos-1];
}
intlocate(ListL,elemtypex)
{ inti=0;
while(ilen&&L->data[i]!
=x)i++;
if(i==L->len)return-1;
elsereturn(i+1);
}
voidinsert(ListL,intpos,elemtypex)
{ intj;
if(pos<1||pos>L->len+1)printf("inserterror\n");
else{
L->len++;
for(j=L->len;j>=pos;j--) L->data[j]=L->data[j-1];
L->data[pos-1]=x;};
}
voiddelnode(ListL,intpos)
{intj;
if(pos<1||pos>L->len)printf("delerror\n");
else{
for(j=pos;jlen;j++)
L->data[j-1]=L->data[j];
L->len--;}
}
voidprint(ListL)
{ inti;
for(i=1;ilen;i++)
printf("%c->",L->data[i-1]);
printf("%c",L->data[L->len-1]);
}
main()
{
inti=1,n;
lnodeL;
charch,x;
init(&L);
printf("\n\n\n*******************************顺序表演示程序***********\n");
printf("请输入你想建立的顺序表的元素,以?
结束:
");
ch=getchar();
while(ch!
='?
')
{insert(&L,i,ch);
i++;
ch=getchar();
};
printf("你建立的顺序表为:
");
print(&L);
printf("\n顺序表的长度为:
%d",L.len);
printf("\n输入你想查找的元素:
");
fflush(stdin);
scanf("%c",&x);
printf("你查找的元素为%c序位为%d",x,locate(&L,x));
printf("\n输入你想查找的元素序位:
");
scanf("%d",&n);
printf("\n你查找的元素为:
%c",getnode(&L,n));
printf("\n输入你想插入的元素以及序位:
<用逗号隔开>");
fflush(stdin);
scanf("%c,%d",&x,&n);
insert(&L,n,x);
printf("\n插入后顺序表为:
");
print(&L);
fflush(stdin);
printf("\n请输入你想删除的元素序位:
");
scanf("%d",&n);
delnode(&L,n);
printf("\n删除后的顺序表为:
");
print(&L);
getch();
}
四、测试结果
运行程序,屏幕显示:
“请输入你想建立的顺序表的元素,以?
结束:
”
输入:
54381
你建立的顺序表为:
5—>4—>3—>8—>1
顺序表的长度为:
5
输入你想查找的元素:
4
你查找的元素为4序位为2
输入你想查找的元素序位:
4
你查找的元素为:
8
输入你想插入的元素以及序位:
<用逗号隔开>":
6,3
插入后顺序表为:
5—>4—>6—>3—>8—>1
请输入你想删除的元素序位:
5
删除后的顺序表为:
5—>4—>6—>3—>1
实验二栈和队列
一、实验目的:
1、掌握队列和栈的顺序存储结构和链式结构,以便在实际背景下灵活运用。
2、掌握栈和队列的特点,即先进后出与先进先出的原则。
二、实验内容:
停车场管理
[问题描述]
设有一个可以停放N辆汽车的狭长停车场,它只有一个大门利用供车辆进出,车辆按到达停车场时间早晚依次可以从停车场最里面向大门处停放(最先到达的第一辆放在停车场最里面)。
然后停车场已放满N辆车,则后来的车辆只能停在车场大门外的便道上等待,一旦停车场有车开走,在它之后进入停车场的车必须先退出停车场为它让路,待其开出停车场后,这些车辆再依原来的次序进场。
每辆车在离开停车场时,都应依据它在停车场内停留的时间长短交费。
如果停留在便道上的未能进停车场就离去,允许它走,不收停车费,而且仍然保持在便道上的等待的车辆的次序。
编制一程序模拟停车场的管理。
[实现要求]
要求程序输出每辆车到达后的停车位置(停车场或便道上),以及某辆车离开停车场时应交的费用和它在停车场内停留时间;
[实现提示]
汽车的模拟输入信息格式可以是:
(到达/离去,汽车牌照号码,到达/离去的时刻)。
例如,(A,1,5)表示1号牌照车在5这个时刻到达,而(D,5,20)表示5号车在20这个时刻离去,整个程序可以在输入信息为(E,0,0)时结束。
本题可用栈和队列来实现。
[程序实现]
(1)设计思想
根据题目要求,停车场只有一个大门,因此可用一个栈来模拟;而当栈满后,继续来的车辆只能停在便道上,根据便道停车的特点,可知这可以用一个队列来模拟,安排队的车辆先离开便道,进入停车场。
由于在停车场中间的车辆可以提出离开停车场,而且要求在离开车辆到停车场大门之间的车辆都必须先离开停车场,让此车离去,然后再让这些车辆依原来的次序进入停车场,因此在一个栈和一个队列的基础上,还需要有一个地方保存为了让路离开停车场的车辆,很显然这也应该用一个栈来模拟。
因此本题中用到两个栈和一个队列。
对于停车场和车辆规避所,有车辆进入和车辆离去两个动作,这就是栈的进栈和出栈操作,只是还允许排在中间的车辆先离开停车场,因此在栈中需要进行查找。
而对于便道,也有入队列和出队列的操作,同样允许排在中间的车辆先离去队列。
这样基本动作只需利用栈和队列的基本操作就可实现。
三、详细设计:
#include"stdio.h"
#defineN5/*定义停车场长度*/
#defineM10
typedefstruct/*定义栈元素的类型*/
{intnum;
intarrtime;
}elemtype;
typedefstruct/*定义栈*/
{elemtypestack[N];
inttop;
}stack;
typedefstructnode/*定义队列节点类型*/
{intnum;
structnode*next;
}queneptr;
typedefstruct/*定义队列*/
{queneptr*front,*rear;
}quene;
voidinitstack(stack*s)/*初始化栈*/
{s->top=-1;
}
intpush(stack*s,elemtypex)/*数据元素X进入指针S所指的栈*/
{if(s->top==N-1)
return(0);
else{s->stack[++s->top]=x;
return
(1);
}
}
elemtypepop(stack*s)
{elemtypex;
if(s->top<0)
{x.num=0;
x.arrtime=0;
return(x);/*如果栈不空,返回栈顶元素*/
}
else{x=s->stack[s->top];
s->top--;
returnx;
}
}
voidinitquene(quene*s)/*初始化队列*/
{s->front=(queneptr*)malloc(sizeof(queneptr));/*产生一个新结点,作为头结点*/
s->rear=s->front;
s->front->next=NULL;
s->front->num=0;/*头结点的NUM保存队列元素的个数*/
}
voidenquene(quene*s,intnum)/*数据入队列*/
{queneptr*p;
p=(queneptr*)malloc(sizeof(queneptr));
p->num=num;
p->next=NULL;
s->rear->next=p;
s->rear=p;
s->front->num++;
}
intdelquene(quene*s)
{queneptr*p;
intn;
if(s->front==s->rear)
return(0);/*如果队列空*/
else{p=s->front->next;
s->front->next=p->next;
if(p->next==NULL)
s->rear=s->front;
n=p->num;
free(p);
s->front->num--;
return(n);
}
}
voidarrive(stack*s1,quene*p,elemtypex)
{intf;
f=push(s1,x);/*新到达的车辆入停车栈*/
if(f==0)
{enquene(p,x.num);/*如果停车场满,就进入队列*/
printf("the%dcarstopsthe%dseatofthequene\n",x.num,p->front->num);
}
elseprintf("the%dcarstopsthe%dseatofthestack\n",x.num,s1->top+1);
}
voidleave(stack*s1,stack*s2,quene*p,elemtypex)/*处理车辆离去函数*/
{intn,f=0;
elemtypey;queneptr*q;
while((s1->top>-1)&&(!
f))
{y=pop(s1);
if(y.num!
=x.num)
n=push(s2,y);
elsef=1;
}
if(y.num==x.num)/*如果栈顶元素不是要离开的车辆,就将其放入车辆规避所*/
{printf("themoneyofthe%dis%dyuan\n",y.num,(x.arrtime-y.arrtime)*M);
while(s2->top>-1)
{y=pop(s2);
f=push(s1,y);
}
n=delquene(p);
if(n)/*在停车场中找到要离开的车辆*/
{y.num=n;
y.arrtime=x.arrtime;
f=push(s1,y);
printf("the%dcarstopsthe%dseatofthestak\n",y.num,s1->top+1);
}
}
else{while(s2->top>-1)/*车辆规避所不空,将其全放回停车场*/
{y=pop(s2);f=push(s1,y);}
q=p->front;f=0;
while(f==0&&q->next!
=NULL)
if(q->next->num!
=x.num)/*如果便道上有车辆,将第一辆车放入停车场*/
q=q->next;
else{q->next=q->next->next;
p->front->num--;
if(q->next==NULL)
p->rear=p->front;
printf("the%dcarleavethequene\n",x.num);
f=1;
}
if(f==0)/*在便道上没有找到要离开的车辆,输出数据错误*/
printf("error!
thestackandthequenehavenothe%dcar\n",x.num);
}
}
voidmain()/*停车场模拟管理程序*/
{charch;
stack*s1,*s2;
quene*p;
elemtypex;
inti=1;
clrscr();
s1=(stack*)malloc(sizeof(stack));
s2=(stack*)malloc(sizeof(stack));
p=(quene*)malloc(sizeof(quene));
initstack(s1);initstack(s2);/*初始化停车规避所栈*/
initquene(p);/*初始化便道队列*/
while(i)
{
printf("whatdoyouwanttodo?
\n");
printf("input---(Add/Del/Exit):
");
scanf("%c",&ch);
switch(ch)
{case'a':
printf("inputthenumber:
\n");
scanf("%d",&x.num);
printf("inputthetime:
\n");
scanf("%d",&x.arrtime);
arrive(s1,p,x);/*车辆到达*/
break;
case'd':
printf("inputthenumber:
\n");
scanf("%d",&x.num);
printf("inputthetime:
\n");
scanf("%d",&x.arrtime);
leave(s1,s2,p,x);/*车辆离开*/
break;
case'e':
printf("theend!
");
i=0;
break;
default:
{printf("inputerror!
---pleaseinputagain:
\n");break;}
}
ch=getchar();
}
}
四、使用说明:
1、按提示输入车进入停车场的情况
2、按提示输入车离开停车场的情况
3、车离开后计算车进入停车场的时间并得出应收费用。
五、测试结果:
运行程序后,屏幕出现
whatdoyouwanttodo?
Input----(add/del/exit)
/*此时停车场为空,a是车进入停车场,d是车离开停车场,e是程序结束。
*/
a
inputthenumber:
/*要求输入停车牌号*/
1
inputthetime:
/*要求输入停车时间*/
2
:
/*屏幕返回到提示,可以按以上方法输入多个数据*/
:
whatdoyouwanttodo?
input----(add/del/exit)/*当输入多个数据后,可以设计车离开*/
d
inputthenumber:
/*要求输入要离开车牌号*/
inputthetime:
/*要求输入车离开的时间*/
5
themoneyofthe1is30yuan/*输出结果,1小时10元计价收费*/
实验三栈
一、实验目的:
1. 熟练掌握栈的结构,以及这种数据结构的特点;
2. 能够在两种存储结构上实现栈的基本运算,特别注意栈满和栈空的判断条件及描述方法;
二、实验内容:
计算表达式的值
【问题描述】
计算用运算符后缀法表示的表达式的值。
后缀表达式也称逆波兰表达式,比中缀表达式计算起来更方便简单些,中缀表达式要计算就存在着括号的匹配问题,所以在计算表达式值时一般都是先转换成后缀表达式,再用后缀法计算表达式的值。
如:
表达式(a+b*c)/d-e用后缀法表示应为abc*+d/e-。
只考虑四则算术运算,且假设输入的操作数均为1位十进制数(0—9),并且输入的后缀形式表达式不含语法错误。
【数据描述】
#defineadd43/*运算符加号‘+’的ASCII码*/
#definesubs45/*运算符减号‘-’的ASCII码*/
#definemult42/*运算符乘号‘*’的ASCII码*/
#definediv47/*运算符除号‘/’的ASCII码*/
#defineMAXSIZE100
typedefstruct{
{intstkdata[MAXSIZE];//用数组来表示栈空间,定义长度为MAXSIZE的栈
inttop;//栈顶指针
}STKzone;
typedefSTKzone*STK;
typedefenum{true=1,false=0}bool;
typedefenum{ok,error}status;
【算法描述】
用流程图表示见图3-4。
【C源程序】
#include
#defineadd43/*运算符加号‘+’的ASCII码*/
#definesubs45/*运算符减号‘-’的ASCII码*/
#definemult42/*运算符乘号‘*’的ASCII码*/
#definediv47/*运算符除号‘/’的ASCII码*/
#defineMAXSIZE100
typedefstruct
{intstkdata[MAXSIZE];/*用数组来表示栈空间,定义长度为MAXSIZE的堆栈*/
inttop;/*栈顶*/
}STKzone;
typedefSTKzone*STK;
typedefenum{true=1,false=0}bool;
typedefenum{ok,error}status;
STKzoneexpSTKzone;
STKexpSTK;
STKinitSTK(STKzone*stack_zone){
/*执行栈初始化,建栈指针*/
STKp;
p=stack_zone;
p->top=0;
}
statuspush(int*term,STKpstk){
/*将一结构型数据送入栈中*/
if(pstk->top==MAXSIZE)
returnerror;/*栈满,进栈失败*/
pstk->stkdata[pstk->top]=*term;
(pstk->top)++;/*栈顶指针移动*/
returnok;
}/*push*/
boolemptySTK(STKpstk){
/*判断栈是否为空栈*/
return(pstk->top==0);
}
statuspop(int*pdata,STKpstk){
/*从栈中取出一结构型数据*/
if(emptySTK(pstk))
returnerror;
(pstk->top)--;/*退栈*/
*pdata=pstk->stkdata[pstk->top];
returnok;
}
voidsynerror()
{printf("\n表达式语法错!
");
exit();
}
inteval(chartag,inta1,inta2)
{switch(tag)
{caseadd:
return(a1+a2);
casesubs:
return(a1-a2);
casemult:
return(a1*a2);
casediv:
return(a1/a2);
}
}
main()
{charc;
intopd1,opd2,temp,c1;
expSTK=initSTK(&expSTKzone);
printf("\n后置表达式:
");
while((c=getchar())!
='\n')
{if(c=='')continue;
if((c>47)&&(c<58))/*判断是否是0—9的字符*/
{putchar(c);
c1=c-48;/*把输入的字符型数字转换成数字*/
if(push(&c1,expSTK)==error)/*运算分量进栈*/
{printf("\n表达式太长\n");
exit();}
}
elseif((c==add)||(c==subs)||(c==mult)||(c==div))
{putchar(c);
if(pop(&opd1,expSTK)==error)/*将运算量1出栈*/
synerror();
if(pop(&opd2,expSTK)==error)/*将运算量2出栈*/
synerror();
temp=eval(c,opd2,opd1);/*计算得到结果*/
push(&temp,expSTK);/*将运算结果进栈*/
}
elsesynerror();/*出现非法字符*/
}/*whil