您的位置:首页 > 理论基础 > 数据结构算法

数据结构-循环队列顺序存储

2017-10-19 22:55 495 查看
目标效果:



dsp0304.cpp:

#include <stdio.h>
#include <stdlib.h>
#include "sqqueue.h"

//初始化系统
void Initialize(SqQueue &q);
//显示操作菜单
void ShowMenu();
//读取用户命令
int GetCommand();
//执行用户命令
int DoCommand(int cmd, SqQueue &q);
//结束执行
void Finalize(SqQueue &q);

void QueueView(SqQueue Q);

////////////////////////////////////////////
//主程序
int main()
{
SqQueue q; //循环队列
int cmd; //用户命令

//系统初始化
Initialize(q);
//显示操作菜单
ShowMenu();
//进入主循环
while(1) {
//读取用户命令(0 表示退出)
cmd = GetCommand();
//执行命令cmd操作队列q
DoCommand(cmd,q);
//退出命令
if( cmd == 0 ) break;  // 退出
}

//结束前执行的操作
Finalize(q);

system("pause"); //暂停
return 0;
}

////////////////////////////////////////////
//函数的定义

//初始化系统
void Initialize(SqQueue &q)
{
InitQueue(q); //初始化队列
}

//显示操作菜单
void ShowMenu()
{
printf("1)EnQueue 2)DeQueue 3)Clear 4)Empty"
" 5)Length 6)Head 7)View 9)Menu 0)Quit\n");
}

//读取用户命令
int GetCommand()
{
int cmd=-1;
printf(">");
scanf("%d", &cmd);
if(cmd<1)
fflush(stdin); //处理输入错误
return cmd;
}

//结束执行
void Finalize(SqQueue &q)
{
DestroyQueue(q); //销毁队列
printf("程序已经结束\n");
}

//执行用户命令cmd, 测试队列的各种操作
//    执行结束后返回命令(便于书写主循环)
int DoCommand(int cmd, SqQueue &q)
{
int e;

switch(cmd) {
case 1: //EnQueue......................
printf("输入入队列的数据:");
scanf("%d",&e);
if(e<1) {
printf("输入错误\n");
fflush(stdin);
} else if(EnQueue(q,e)==OK)
printf("入队列成功\n" );
else
printf("入队列失败\n");
break;
case 2: //DeQueue......................
if( DeQueue(q,e)==OK )
printf("%d 出队列\n", e);
else
printf("出队列失败\n");
break;
case 3: //Clear........................
if(ClearQueue(q)==OK)
printf("队列已清空\n");
else
printf("清空队列失败\n");
break;
case 4: //Empty........................
if(QueueEmpty(q)==TRUE)
printf("队列空\n" );
else
printf("队列不空\n");
break;
case 5: //Length.......................
printf("队列长度: %d\n", QueueLength(q));
break;
case 6: //Head.........................
if(GetHead(q,e)==OK)
printf("队头元素: %d\n", e);
else
printf("取队头元素失败\n");
break;
case 7: //View.........................
/* TODO (#9#): 实现SqQueue类型后使用QueueView()函数 */
QueueView(q);
break;
case 9: //Menu.........................
ShowMenu();
case 0: //Quit.........................
//后面 return cmd; 返回0可以结束主循环
break;
default:
printf("命令错误\n");
}

return cmd; //返回最近执行的命令
}


squeue.h:
#ifndef SQQUEUE_H_INCLUDED
#define SQQUEUE_H_INCLUDED /* 防止重复包含 */

//////////////////////////////////////////
//包含头文件
#include <stdlib.h>
#include "ds.h" // OK, Status 等定义

//数据元素的类型(缺省使用int型)
#ifndef ElemType
#define ElemType int
#define USE_DEFAULT_ELEMTYPE /* 使用缺省类型的标志 */
#endif //ElemType

//////////////////////////////////////////
//循环队列的存储结构

#define MAXQSIZE 64 /* 循环队列的最大容量 */
typedef struct {
ElemType *base;
int front;
int rear;
} SqQueue;

//////////////////////////////////////////
//循环队列的基本操作

//构造一个空队列Q
Status InitQueue(SqQueue &Q)
{
Q.base=(ElemType *)malloc(MAXQSIZE*sizeof(ElemType));
if(!Q.base)
return ERROR; //TODO: 替换这行代码,以下同
Q.front=Q.rear=0;
return OK;
}

//销毁队列Q
//  前提:队列Q已存在
Status DestroyQueue(SqQueue &Q)
{
if(!Q.base)
return ERROR;
Q.rear=Q.front;
free(Q.base);
return OK;
}

//将队列Q清为空队列
//  前提:队列Q已存在
Status ClearQueue(SqQueue &Q)
{
if(!Q.base)
return ERROR;
Q.rear=Q.front;
return OK;
}

//若队列Q为空,则返回TRUE,否则FALSE
//  前提:队列Q已存在
Status QueueEmpty(SqQueue Q)
{
if(Q.rear==Q.front)
return TRUE;
return FALSE;
}

//返回队列Q的元素个数,即队列长度
//  前提:队列Q已存在
int QueueLength(SqQueue Q)
{
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
}

//取队列Q头元素用e返回
//  前提:队列Q存在且非空
Status GetHead(SqQueue Q, ElemType &e)
{
if(!Q.base&&Q.rear==Q.front)
return ERROR;//返回操作状态(成功:OK,失败:ERROR)
e=Q.base[Q.front];
return OK;
}

//插入元素e作为队列Q的新的队尾元素
//  前提:队列Q存在且未满
Status EnQueue(SqQueue &Q, ElemType &e)
{
if((Q.rear+1)%MAXQSIZE==Q.front)
return ERROR;//返回操作状态(成功:OK,失败:ERROR)
Q.base[Q.rear]=e;
Q.rear=(Q.rear+1)%MAXQSIZE;
return OK;
}

//删除队列Q的队头元素,并用e返回
//  前提:队列Q存在且非空
Status DeQueue(SqQueue &Q, ElemType &e)
{
if(Q.front==Q.rear)
return ERROR;//返回操作状态(成功:OK,失败:ERROR)
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}

//////////////////////////////////////////

//TODO: 定义好 SqQueue 类型后使用 QueueView 函数
//#include <stdio.h>
//查看队列状态(调试用)
void QueueView(SqQueue Q)
{
int i=0;
if(Q.front<0||Q.front>=MAXQSIZE||Q.rear<0||Q.rear>=MAXQSIZE){
printf("队列未初始化\n");
return ;
}
printf("---Queue View---\n");
printf("front=%d , rear=%d\n", Q.front, Q.rear);
if(Q.rear>=Q.front) {
printf(".....   ......\n");
for(i=Q.front; i<Q.rear; i++) {
printf("%5d\t", i);
printf("%d",Q.base[i]);
printf("\n");
}
if(i<MAXQSIZE) printf(".....   ......\n");
} else {
for(i=0; i<Q.rear; i++) {
printf("%5d\t", i);
printf("%d",Q.base[i]);
printf("\n");
}
printf(".....   ......\n");
for(i=Q.front; i<MAXQSIZE; i++) {
printf("%5d\t", i);
printf("%d",Q.base[i]);
printf("\n");
}
}
printf("--- view end ---\n");
}

//取消ElemType的默认定义,以免影响其它部分
#ifdef USE_DEFAULT_ELEMTYPE
#undef ElemType
#undef USE_EFAULT_ELEMTYPE
#endif

#endif //SQQUEUE_H_INCLUDED


源码下载:点击打开链接

1.前几次我一直没有加ds.h页面,里边就是定义了return ok这种形式,以及read读入方法的总写,没比较核心的内容,所以之前我都去掉这个页面,方法返回值return ok都用return true来表示。不够今天不太想那样改了,没多大用,纯自己的强迫症。代码没贴出来,不过在代码链接里可以下载。

2.这里的入队需要单个元素进行入队。

3.另外注意一个地方,原先老师发的框架里,输入一个数值并判断是  if(scanf("%d", &cmd)<1),但是这样即使输入了一个不合法的值还是不会进if语句,后来查了一个是因为scanf()有返回值,但是会返回本次输入的个数,因为入队每次都是1个元素,所以scanf()返回的都是1,所以不会进入if语句,这里需要改成我代码中的格式,即先输入然后判断。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: