数据结构实验报告队列的表示与实现.docx
- 文档编号:7410642
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:18
- 大小:18.80KB
数据结构实验报告队列的表示与实现.docx
《数据结构实验报告队列的表示与实现.docx》由会员分享,可在线阅读,更多相关《数据结构实验报告队列的表示与实现.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构实验报告队列的表示与实现
数据结构实验报告
姓名
学号
号
实验地点
数学楼
指导教师
实验
名称
队列的表示与实现
1、实验目的
了解和掌握队列的数据类型描述及其特点;
完成链队列的初始化、入队、出队、取对头元素、显示操作的实现;
掌握队列的链式存储表示与基本操作算法实现;
掌握队列在实际问题中的应用和基本编程技巧。
2、实验方法
队列的抽象数据类型定义:
ADTQueue{
//数据对象:
D={a[i]|a[i]∈ElemSet,i=1,2,...,n,n>=0}
//数据关系:
//约定其中a[1]端为队列头,a[n]端为队列尾
//基本操作:
InitQueue(&Q)//操作结果:
构造一个空队列Q。
DestoryQueue(&Q)//初始条件:
队列Q已存在
//操作结果:
队列Q被销毁,不再存在
ClearQueue(&Q)//初始条件:
队列Q已存在
//操作结果:
将Q清为空队列
QueueEmpty(Q)//初始条件:
队列Q已存在
//操作结果:
若队列Q为空队列,则返回TRUE,否则FALSE
QueueLength(Q)//初始条件:
队列Q已存在
//操作结果:
返回Q的元素个数,即队列的长度
GetHead(Q,&e)//初始条件:
Q为非空队列
//操作结果:
用e返回Q的队头元素
EnQueue(&Q,e)//初始条件:
队列Q已存在
//操作结果:
插入元素e为Q的新的队尾元素
DeQueue(&Q,&e)//初始条件:
Q为非空队列
//操作结果:
删除Q的队头元素,并用e返回其值
QueueTraverse(Q,visit())//初始条件:
Q已存在且非空
//操作结果:
从队头到队尾,依次对Q的每个数据元素调用函数visit()。
一旦visit()失败,则操作失败。
}ADTQueue
与线性表类似,队列有两种存储表示链队列和循环队列。
//-----基本操作的函数原型说明-----
statusINitQueue(LinkQueue&Q)//构造一个空队列Q
StatusDestoryQueue(LinkQueue&Q)//销毁队列Q,Q不再存在
StatusClearQueue(LinkQueue&Q)//将Q清为空队列
StatusQueueEmpty(LinkQueueQ)
//若队列Q为空队列,则返回TRUE,否则返回FALSE
intQueueLength(LinkQueueQ)//返回Q的元素个数,即为队列的长度
StatusGetHead(LinkQueueQ,QElemType&e)
//若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
StatusENQueue(LinkQueue&Q,QElemTypee)//插入元素e为Q的新的队尾元素
StatusDeQueue(LinkQueue&Q,QElemType&e)
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
statusQueueTraverse(linkQueueQ,visit())
//从队头到队尾依次对队列Q中的每个元素调用函数visit()。
一旦visit失败,则操作失败。
链队列:
//单链队列——队列的链式存储结构
typedefstructQNode{
QElemTypedata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct{
QueuePtrfront;//队头指针
QueuePtrrear;//队尾指针
}LinkQueue;
//-----单链队列的基本操作的算法描述------
statusINitQueue(LinkQueue&Q){//构造一个空队列Q
Q.front=Q.rear=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.front)exit(OVERFLOW);//存储分配失败
Q.front->next=NULL;
returnOK;}
StatusDestoryQueue(LinkQueue&Q){//销毁队列Q,Q不再存在
while(Q.front){
Q.rear=Q.front->next;
free(Q.front);
Q.front=Q.rear;}
returnOK;}
StatusClearQueue(LinkQueue&Q)
//将Q清为空队列
StatusQueueEmpty(LinkQueueQ)
//若队列Q为空队列,则返回TRUE,否则返回FALSE
intQueueLength(LinkQueueQ)
//返回Q的元素个数,即为队列的长度
StatusGetHead(LinkQueueQ,QElemType&e)
//若队列不空,则用e返回Q的队头元素,并返回OK;否则返回ERROR
StatusENQueue(LinkQueue&Q,QElemTypee){//插入元素e为Q的新的队尾元素
p=(QueuePtr)malloc(sizeof(QNode));
if(!
p)exit(OVERFLOW);//存储分配失败
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;
returnOK;}
StatusDeQueue(LinkQueue&Q,QElemType&e){
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;否则返回ERROR
if(Q.front==Q.rear)returnERROR;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(Q.rear==p)Q.rear=Q.front;
free(p);
returnOK;}
statusQueueTraverse(linkQueueQ,visit())
//从队头到队尾依次对队列Q中的每个元素调用函数visit()。
//一旦visit失败,则操作失败。
循环队列:
//循环队列——队列的顺序存储结构
#defineMAXQSIZE100//最大队列长度
typedefstruct{
QElemType*base;//初始化的动态分配存储空间
intfront;//头指针,若队列不空,指向队列头元素
intrear;//尾指针,若队列不空,指向队列尾元素的下一个位置
}SqQueue;
//-----循环队列的基本操作的算法描述------
StatusInitQueue(SqQueue&Q){
//构造一个空队列Q
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!
Q.base)exit(OVERFLOW);//存储分配失败
Q.front=Q.rear=0;
returnOK;
}
intQueueLength(SqQueueQ){//返回Q的元素个数,即队列的长度
return(Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;}
statusEnQueue(SqQueue&Q,QElemType){//插入元素e为Q的新的队尾元素
if((Q.rear+1)%MAXQSIZE==Q.front)returnERROR;//队列满
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
returnOK;}
StatusDeQueue(Squeue&Q,QElemType&e){
//若队列不空,则删除Q的队头元素,用e返回其值,并返回OK;
//否则返回ERROR
if(Q.front==Q.rear)returnERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
returnOK;
}
3、事先定义的常量和类型
/***********************C函数库定义****************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
/******************函数结果状态代码****************/
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
//#defineOVERFLOW-2//因为math.h中已经定义OVERFLOW为3
typedefintQElemType;//ElemType是变量的类型定义
typedefintStatus;//Status是函数的类型,其值是函数结果状态代码,如OK,TRUE。
4、实验过程
链队列
#include
#include
#include
#defineOK1
#defineERROR0
#defineOVERFLOW0
typedefstructQNode
{
intdata;
structQNode*next;
}QNode,*QueuePtr;
typedefstruct
{
QueuePtrfront;
QueuePtrrear;
}LinkQueue;
intInitQueue(LinkQueue&Q)
{
Q.rear=Q.front=(QueuePtr)malloc(sizeof(QNode));
if(!
Q.rear)
exit(OVERFLOW);
Q.front->next=NULL;
returnOK;
}
voidQueueEmpty(LinkQueueQ)
{
if(Q.front==Q.rear)
printf("该链队为空:
");
else
printf("该链队不为空:
");
}
voidEnQueue(LinkQueue&Q,inte)
{
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!
p)
printf("error");
p->data=e;
Q.rear->next=p;
Q.rear=p;
printf("元素%d入队成功",e);
}
intEnnQueue(LinkQueue&Q,inte)
{
QueuePtrp;
p=(QueuePtr)malloc(sizeof(QNode));
if(!
p)
returnERROR;
p->data=e;
Q.rear->next=p;
Q.rear=p;
returnOK;
}
voidDeQueue(LinkQueue&Q)
{
QueuePtrp;
if(Q.front==Q.rear)
printf("该链队为空");
p=Q.front->next;
Q.front->next=p->next;
if(Q.rear==p)
Q.rear=Q.front;
free(p);
printf("队首元素删除成功");
}
voidGetHead(LinkQueue&Q)
{
QueuePtrp;
if(Q.front==Q.rear)
printf("该链队为空");
p=Q.front->next;
printf("队首元素为:
%d",p->data);
}
voidOutQueue(LinkQueue&Q)
{
QueuePtrp;
if(Q.front==Q.rear)
printf("该链队为空");
p=Q.front->next;
while(p!
=Q.rear->next)
{
printf("%d",p->data);
p=p->next;
}
}
voidLengthQueue(LinkQueue&Q)
{
intf=0;
QueuePtrp;
if(Q.front==Q.rear)
printf("该队列的长度是:
%d",f);
else
{
p=Q.front->next;
while(p!
=Q.rear->next)
{
p=p->next;
f++;
}
printf("该队列的长度是:
%d",f);
}
}
voidmain()
{
system("cls");
intflag=1,i;
LinkQueueQ;
InitQueue(Q);
printf("************************链队列功能菜单***********************\n");
printf("1:
初始化链队列,2:
判断链队列是否为空,3:
进入队列,4:
取出队首元素\n");
printf("5:
输出该队列的所有元素,6:
输出该队列的长度,7:
结束程序,8:
清屏\n");
while(flag)
{
printf("\n请输入操作符:
");
scanf("%d",&i);
switch(i)
{
case1:
inte,n,k;
printf("请输入队列的长度:
");
scanf("%d",&n);
printf("请输入队列的元素:
");
for(e=1;e<=n;e++)
{
scanf("%d",&k);
EnnQueue(Q,k);
}
printf("初始化链队成功");
break;
case2:
QueueEmpty(Q);
break;
case3:
intj;
printf("请输入要进入队列的元素");
scanf("%d",&j);
EnQueue(Q,j);
break;
case4:
GetHead(Q);
break;
case5:
printf("该队列的元素是:
");
OutQueue(Q);
break;
case6:
LengthQueue(Q);
break;
case7:
flag=0;
break;
case8:
system("cls");
break;
}
}
printf("程序结束");
}
循环队列
#include
#include
#include
#defineMAXSIZE10;
#defineOK1;
#defineERROR0;
#defineOVERFLOW0;
typedefstruct
{
int*data;
intfront;
intrear;
}SqQueue;
intInitQueue_Sq(SqQueue&Q)
{
Q.data=(int*)malloc(10*sizeof(int));
if(!
Q.data)
exit(0);
Q.front=Q.rear=0;
returnOK;
}
intEnQueue_Sq(SqQueue&Q,inte)
{
if((Q.rear+1)%10==Q.front)
returnERROR;
Q.data[Q.rear]=e;
Q.rear=(Q.rear+1)%10;
returnOK;
}
voidIfEmpty(SqQueueQ)
{
if(Q.rear=Q.front)
printf("该循环队列是空队列\n");
else
printf("该循环队列不是空队列\n");
}
voidIfFull(SqQueueQ)
{
if((Q.rear+1)%10==Q.front)
printf("该循环队列已满\n");
else
printf("该循环队列未满\n");
}
voidInQueue_Sq(SqQueue&Q,inte)
{
if((Q.rear+1)%10==Q.front)
printf("循环队列已满\n");
else
{
Q.data[Q.rear]=e;
Q.rear=(Q.rear+1)%10;
printf("元素%d成功进入循环队列\n",e);
}
}
voidDeQueue_Sq(SqQueue&Q)
{
inte;
if(Q.front==Q.rear)
printf("循环队列为空\n");
e=Q.data[Q.front];
printf("循环队列队首元素是:
%d\n",e);
}
voidDE_Sq(SqQueue&Q)
{
int*w;
w=&Q.data[Q.front];
Q.front=Q.front+1;
printf("队首元数%d删除成功\n",*w);
}
intLength_Sq(SqQueue&Q)
{
ints;
s=(Q.rear-Q.front+10);
returns%10;
}
intOutQueue_Sq(SqQueueQ)
{
SqQueuep;
p=Q;
inti,n;
n=Length_Sq(p);
for(i=0;i { printf("%d",p.data[p.front]); p.front++; } returnOK; } voidDelet(SqQueue&Q) { free(Q.data); printf("释放成功"); } voidmain() { system("cls"); printf("**********************循环队列功能菜单***********************\n"); printf("1.初始化队列输入的数不超过10个,2.判断队列是否空,3.判断队列是否满,\n"); printf("4.将元素入队,5.取队列首元素,6.队列的长度,7.遍历循环队列,\n"); printf("8.删除队首元素,9.释放队列,10.清屏,0.结束程序,\n"); intflag=1,i; SqQueueQ; InitQueue_Sq(Q); while(flag) { printf("请输入操作符: "); scanf("%d",&i); switch(i) { case1: intn,j,m; printf("请输入初始化元素的个数: "); scanf("%d",&n); printf("请输入元素: "); for(j=0;j { scanf("%d",&m); EnQueue_Sq(Q,m); } break; case2: IfEmpty(Q); break; case3: IfFull(Q); break; case4: intk; printf("请输入要进入循环队列的元素: "); scanf("%d",&k); InQueue_Sq(Q,k); break; case5: DeQueue_Sq(Q); break; case6: intf; f=Length_Sq(Q); printf("该循环队列的长度为: %d\n",f); break; case7: printf("该循环队列为: "); OutQueue_Sq(Q); printf("\n"); break; case8: DE_Sq(Q); break; case9: Delet(Q); break; case10: system("cls"); break; case0: flag=0; break; } } printf("程序结束"); } 4、实验总结 队列是一种先进先出的线性表,它只允许在表的一端进行插入,而在另一端删除元素,在C语言中不能用动态分配的一维数组来实现循环队列,如果用户的应用程序中设有循环队列,则必须为它设定一个最大队列长度;若用户无法预估所用队列的最大长度,则宜采用链队列。 本次实验通过对队列的链式表示与实现、队列的顺序表示与实现,加深了对链队列和循环队列的特点的理解,并且熟悉了VC6.0集成环境,虽然在调试过程中遇到了一些问题,但经分析后达到了预期的结果。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 实验 报告 队列 表示 实现
![提示](https://static.bdocx.com/images/bang_tan.gif)