一、 目的
1.掌握队列的思想及其存储实现。
2.掌握队列的常见算法的程序实现。
二、内容
1、内容
2、采用顺序存储实现循环队列的初始化、入队、出队操作。
3、采用链式存储实现队列的初始化、入队、出队操作。
4、在主函数中设计一个简单的菜单,分别测试上述算法。
5、*综合训练:
银行排队系统模拟:请用一个队列来模拟银行排队系统,队列中存储序号。请设置一个菜单,包括叫号和排号两个选项。若选择叫号,则输出并删除队首元素;若选择排号,则顺序生成一个序号,加入队列,并输出该序号和前面有多少人等候。
6、主要数据类型与变量
1.类型定义
循环队列示例
#define MAXQSIZE100 //队列的最大长度
typedef struct
{ QElemType *base;
int front;
int rear;
}SqQueue;
链队列示例
typedef struct QNode
{
QElemType data;
struct QNode *next;
}QNode, *QueuePtr;
typedef struct {
QueuePtr front;
QueuePtr rear;
}LinkQueue;
7、算法思想描述
构建队列模型,通过后台在这里面完成逻辑操作。
三、系统测试
1、测试方案
通过完成代码,在控制台输出图形化界面。在图形化界面上操作,完成所有的功能。
2、测试结果
1.循环队列初始化和参数入队
执行多次后
2.循环队列遍历,及出队操作
3.计算循环队列的长度
4.初始化链式队列和入队操作
执行多次后
5.出队操作
四、 总结与讨论
由于在这次之前,已经开始着手做了一点,所以在本次课堂之上时,便已经将代码写好,不过由于对所学的不够系统,没能够将入队操作写成完全式的,就是一次操作,便将入队操作完全完成,这是本次的一个特别大的失误之处。在本次中,自己也遇到了一些麻烦,比如说在构建循环队列的时候,自己的循环这个词理解的不够深刻,第一次并没有将真正的循环做出来,还是和数组一样,能够无线存储的,这不算是太大的问题,不过问题致命,所以我请教了老师,还好,在最后终于将所有的代码完成,虽然这次有点不够完整。但是对于知识的了解自己做到了很深的程度。
附:程序源代码
1.Queue.h
#include "DS.h"
#define MAXQSIZE 100
typedef int QElemType;
/*顺序对列*/
typedef struct {
QElemType *base; /*初始化动态分配存储空间*/
QElemType front; /* 头指针,指向队头元素*/
QElemType rear; /*尾指针,指向队尾元素的下一个位置*/
}SqQueue;
/*链式队列*/
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct LinkQueue{
QueuePtr front;
QueuePtr rear;
}LinkQueue;
void menu();
/*顺序队列*/
Status InitQueue(SqQueue &Q); /*队列的初始化*/
Status QueueLength(SqQueue Q); /*返回队列长度*/
Status EnQueue(SqQueue &Q,QElemTypee); /*向循环队列插入元素*/
Status DeQueue(SqQueue &Q,QElemType&e); /*删除循环队列头部元素*/
void PrintfSqQueue(SqQueue Q); /*遍历循环队列*/
/*链式队列*/
Status InitLinkQueue(LinkQueue &LQ);
Status DestroyLinkQueue(LinkQueue&QL); /*销毁队列*/
Status EnLinkQueue(LinkQueue&LQ,QElemType e); /*为链式队列插入数据*/
Status DeLinkQueue(LinkQueue&LQ,QElemType &e); /*链式队列出队*/
void PrintfLinkQueue(LinkQueue LQ); /*遍历链式队列*/
2.DS.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
typedef int Status;
3.main.cpp
#include "queue.h"
int main()
{
SqQueue Q;
LinkQueue LQ;
QElemType choice,e;
while(1){
menu();
scanf("%d",&choice);
switch (choice){
case 1:
if(InitQueue(Q))
printf("循环队列初始化成功\n");
else
printf("循环队列初始化失败");
break;
case 2:
PrintfSqQueue(Q);
break;
case 3:
printf("循环队列的长度为:%d\n",QueueLength(Q));
break;
case 4:
printf("请输入一个数: \n");
scanf("%d",&e);
if(EnQueue(Q,e))
printf("入队成功\n");
else
printf("入队失败\n");
printf("新队列为:\n");
PrintfSqQueue(Q);
break;
case 5:
if(DeQueue(Q,e))
printf("删除成功,被删除的元素为: %d\n",e);
else
printf("删除失败\n");
printf("新队列为:\n");
PrintfSqQueue(Q);
break;
case 6:
if(InitLinkQueue(LQ))
printf("链式队列初始化成功\n");
else
printf("链式队列初始化失败\n");
break;
case 7:
PrintfLinkQueue(LQ);
break;
case 8:
printf("请输入一个数:\n");
scanf("%d",&e);
if(EnLinkQueue(LQ,e))
printf("添加成功\n");
else
printf("添加失败\n");
printf("新队列为:\n");
PrintfLinkQueue(LQ);
break;
case 9:
if(DeLinkQueue(LQ,e))
printf("删除成功,删除的元素为: %d\n",e);
else
printf("删除失败\n");
printf("新队列为:\n");
PrintfLinkQueue(LQ);
break;
case 10:
printf("销毁成功\n");
DestroyLinkQueue(LQ);
break;
case 0:
exit(-1);
default:
printf("输入错误,请重新输入\n");
}
}
}
4.Queue.cpp
#include "Queue.h"
void menu()
{
printf("\t\t\t 队列的基本操作\n\n");
printf("\t\t\t1.初始化 循环队列\n");
printf("\t\t\t2.遍 历 循环队列\n");
printf("\t\t\t3.计 算 循环队列 长度\n");
printf("\t\t\t4.循环队列 入队\n");
printf("\t\t\t5.循环队列 出队\n");
printf("------------------------------------------------\n");
printf("\t\t\t6.初始化 链式队列\n");
printf("\t\t\t7.遍 历 链式队列\n");
printf("\t\t\t8.链式队列 入队\n");
printf("\t\t\t9.链式队列 出队\n");
printf("\t\t\t10.销毁链式队列\n");
printf("\t\t\t0.退 出\n\n");
printf("请输入需要执行的序号:\n");
}
/*顺序队列*/
/*队列的初始化*/
Status InitQueue(SqQueue &Q){
//构造一个空队列Q
Q.base = (QElemType *) malloc(MAXQSIZE * sizeof(QElemType));
if(!Q.base) exit(OVERFLOW); //存储分配失败
Q.front = Q.rear = 0;
return OK;
}
/*遍 历 循环队列*/
void PrintfSqQueue(SqQueue Q){
int i=Q.front;
printf("遍历结果为:\n");
while (i!=Q.rear)
{
printf("%d ",Q.base[i]);
i++;
}
}
/*返回队列长度*/
QElemType QueueLength(SqQueue Q){
return (Q.rear-Q.front + MAXQSIZE) % MAXQSIZE;
}
/*向循环队列插入元素*/
Status EnQueue(SqQueue &Q,QElemType e){
if((Q.rear+1) % MAXQSIZE == Q.front) return ERROR; //队列满
Q.base[Q.rear] = e;
Q.rear = (Q.rear + 1) % MAXQSIZE;
return OK;
}
/*删除循环队列头部元素*/
Status DeQueue(SqQueue &Q,QElemType&e){
if(Q.front == Q.rear) return ERROR;
e= Q.base[Q.front];
Q.front = (Q.front + 1) % MAXQSIZE;
return OK;
}
/*链式队列*/
/*构建一个空队列LQ*/
Status InitLinkQueue(LinkQueue &LQ){
LQ.front = LQ.rear = (QueuePtr)malloc(sizeof(QNode));
if(!LQ.front) exit(OVERFLOW);
LQ.front->next = NULL;
return OK;
}
/*遍历链式队列*/
void PrintfLinkQueue(LinkQueue LQ){
printf("链式队列遍历如下\n");
if(LQ.front == LQ.rear)
printf("空队列\n");
else{
QueuePtr p;
p = LQ.front->next;
while(p != NULL){
printf("%d ",p->data);
p=p->next;
}
}
}
/*销毁队列*/
Status DestroyLinkQueue(LinkQueue &LQ){
while(LQ.front){
LQ.rear = LQ.front->next;
free(LQ.front);
LQ.front = LQ.rear;
}
return OK;
}
/*为链式队列插入数据*/
Status EnLinkQueue(LinkQueue&LQ,QElemType e){
QueuePtr p;
p= (QueuePtr)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data = e;
p->next = NULL;
LQ.rear->next = p;
LQ.rear = p;
return OK;
}
/*链式队列出队*/
Status DeLinkQueue(LinkQueue&LQ,QElemType &e){
if(LQ.front == LQ.rear) return ERROR;
QueuePtr p;
p= LQ.front->next;
e= p->data;
LQ.front->next = p->next;
if(LQ.rear == p)
LQ.rear=LQ.front;
free(p);
return OK;
}