文章目录
一,什么是队列
二,循环队列
三,银行系统的代码(可直接运行)
1.什么是队列:
队列是一种遵循某一原则(FIFO)的线性表.
队列的分类: 顺序表示和链式表示
#defien MAXSIZE 100
typedef struct
{
QELEMType *base;
int front; //头
int rear; //尾巴
}Sequeue;
并在此约定,当创建空队列的时候,当front = rear = 0;
每当有新的队尾元素时,尾指针rear增 1--------删除队列头元素时候,头指针front增加 1
强调:头指针始终指向队列头元素,尾指针始终指向队列为元素的下一个位置。
当前的SIZEMAX=5,但是如果你在图4的情况下再次插入一个元素的时候就会出现“溢出”的现象,从而使数组越界程序不能运行,但是你又发现,当我的front指的是D的时候,依然图4,添加后还是会溢出,但是我的数组并没有满,那将这一称为“假溢出”。
二,循环队列怎样解决假溢出的问题?------------------如果我是一个圆圈,我的不是可以一直用了吗,就形成了一种环装的循环列表:循环队列.
循环队列采用的处理方式是;少用一个元素的空间,当SIZEMAX=n的时候,那当n-1个元素是就显示队满了,当front和rear的指针的值相同时,就为队空,尾指针在循环里加一后若等于头指针,队满. 判断条件
队满 Q.friont==Q.rear
队满:(Q.rear+1)%SIZEMAX==Q.front
对于循环列表的初始化(目的是让head和tail为0):
CycQueue* CycQueueInit()
{
CycQueue* q; //指针,为了指向地址
if (q = (CycQueue*)malloc(sizeof(CycQueue)))
{
q->head = 0; //使其头和尾开始都为0
q->tail = 0;
return q;
}else
return NULL;
}
因为队列是由malloc函数申请的空间来保存元素的值,so,在不用的时候要进行释放
void CycQueueFree(CycQueue* q)
{
if (q != NULL)
free(q); //空间的释放
}
接下来考虑队列的性质-是否为空 是否已满 (为空的条件是首尾相等)
int CycQueueIsEmpty(CycQueue* q)
{
return (q->head==q->tail); //是否为空
}
int CycQueueIsFull(CycQueue* q)
{
return ((q->tail+1)% QUEUEMAX==q->head);//是否已满
}
那么就看入队元素,入队之前不要忘记判断,(入队尾指针加一,头指针不动)
int CycQueueIn(CycQueue* q, DATA data) //入队操作
{
if ((q->tail+1) % QUEUEMAX==q->head)
{
printf("队列已满!n");
return 0;
}
else { //可添加
q->tail = (q->tail + 1) % QUEUEMAX;
q->data[q->tail++] = data; //q->tail++ 通过自增一开储存新的元素
return 1;
}
}
既然入队了,怎么着也待出队吧,那么依旧先判断,在动头指针,不动尾指针
DATA* CycQueueOut(CycQueue* q)
{
if (q->head == q->tail)
{
printf("n队列已空!n");
return NULL;
}
else { //成功条件
q->head = (q->head + 1) % QUEUEMAX; //那个求余的方法
return &(q->data[q->head++]); //依然向后移动一,头指针始终指向头元素
}
}
还有一个就是获取头元素,这个没有让其出队,不用头指针向后进行移动一位.
DATA* CycQueuePeek(CycQueue* q)
{
if (q->head==q->tail)
{
printf("n队列为空!n");
return NULL;
}
else {
return &(q->data[(q->head+1)%QUEUEMAX]);
}
}
有没有感觉忘记点什么? 我的长度呢? 在这呢
int CycQueueLen(CycQueue* q)
{
int n;
n = q->tail - q->head;
if (n < 0)
n = QUEUEMAX + n;
return n/2;
}
上述是对于整个循环队列的分析,那么加上main函数我们可以跑一下.
三,银行系统的代码(可直接运行)这个是CycQueue.h
#define QUEUEMAX 15
typedef struct
{
long time;
int num;
}DATA;
typedef struct
{
DATA data[QUEUEMAX];
int head;
int tail;
}CycQueue;
CycQueue* CycQueueInit(); //进行初始化
void CycQueueFree(CycQueue* q); //释放空间
int CycQueueIsEmpty(CycQueue* q);//空的
int CycQueueIsFull(CycQueue* q); //满的
int CycQueueLen(CycQueue* q);//长度
int CycQueueIn(CycQueue* q,DATA data);//入队操作
DATA* CycQueueOut(CycQueue* q); //出队
DATA* CycQueuePeek(CycQueue* q);//获取头文件
CycQueue(函数的定义).c
#include "SqeQueue.h" #include#include //对应的malloc分配空间 CycQueue* CycQueueInit() { CycQueue* q; //指针,为了指向地址 if (q = (CycQueue*)malloc(sizeof(CycQueue))) { q->head = 0; //使其头和尾开始都为0 q->tail = 0; return q; }else return NULL; } void CycQueueFree(CycQueue* q) { if (q != NULL) free(q); //空间的释放 } int CycQueueIsEmpty(CycQueue* q) { return (q->head==q->tail); } int CycQueueIsFull(CycQueue* q) { return ((q->tail+1)% QUEUEMAX==q->head); } int CycQueueIn(CycQueue* q, DATA data) //入队操作 { if ((q->tail+1) % QUEUEMAX==q->head) { printf("队列已满!n"); return 0; } else { q->tail = (q->tail + 1) % QUEUEMAX; q->data[q->tail++] = data; return 1; } } DATA* CycQueueOut(CycQueue* q) { if (q->head == q->tail) { printf("n队列已空!n"); return NULL; } else { q->head = (q->head + 1) % QUEUEMAX; //那个求余的方法 return &(q->data[q->head++]); } } int CycQueueLen(CycQueue* q) { int n; n = q->tail - q->head; if (n < 0) n = QUEUEMAX + n; return n/2; } DATA* CycQueuePeek(CycQueue* q) { if (q->head==q->tail) { printf("n队列为空!n"); return NULL; } else { return &(q->data[(q->head+1)%QUEUEMAX]); } }
main函数的代码
#include "SqeQueue.h" #include#include #include int num; void add(CycQueue* q) { DATA data; if (!CycQueueIsFull(q)) { data.num = num++; data.time = time(NULL); CycQueueIn(q, data); } else printf("排队的太多,请稍后在排队!n"); } void next(CycQueue* q) { DATA* data; if (!CycQueueIsFull(q)) { data = CycQueueOut(q); printf("n正在为编号为%d的顾客办理业务!n", data->num); } if (!CycQueueIsFull(q)) { data = CycQueuePeek(q); printf("请编号为%d的顾客准备,马上将为您办理业务!n", data->num); } } int main() { CycQueue* queue1; int i, n,choose; int select; num = 0; queue1 = CycQueueInit(); //初始化队列 if (queue1 == NULL) { printf("创建队列出错!n"); getchar(); return 0; } do { printf("n1.新的顾客:n"); printf("n2.next onen"); printf("n0.outn"); printf("n请选择具体的操作:"); //fflush(stdin); //键盘的输入 scanf_s("%d", &choose); select = choose; switch(select) { case 1:add(queue1); printf("n现在共有%d为顾客在等候!n", CycQueueLen(queue1)); break; case 2:next(queue1); printf("n现在共有%d为顾客在等候!n", CycQueueLen(queue1)); break; case 0: break; } } while (select != 0); CycQueueFree(queue1); getchar(); return 0; }
运行的截图
上方的图片理解来自于:【数据结构】队列(顺序队列、循环队列、链队列)_Jacky_Feng的博客-CSDN博客
我的栈也有自己的想法若有兴趣,可以一看:【数据结构】-栈的基本操作(源码可以直接运行)_i-阿松!的博客-CSDN博客



