文章目录
一. 循环队列的引入
上一篇博客总结了队列的链式存储,队列还有一种存储方式那就是顺序存储,大致是这样:
rear总是指向队列中可用的位置,当有新元素插入队列,则rear++,但是会存在这么一种情况,因为使用的顺序存储结构,队列的长度是固定的,必然会有队列已满的状态,然而,加入此时队列头有元素出队,那么就会有下面这种情况:
这时,就出现了明明队列没满,但是已经无法在添加新元素的情况,称之为假溢出,所以,引入循环队列:
二. 原理演示
- 添加元素5,rear++
- 添加元素8
- 输出5,front++
- 队满
通常留一个位置来存放尾指针,避免了队空与队满的条件都是rear==front从而无法判断的问题,
则队满:(rear+1) % MAXSIZE == front;
三. 定义
#define ElemType int
#define MAXSIZE 100
typedef struct
{
ElemType *base; //存放基地址
int front;
int rear;
}CycleQueue;
在这里,base用来保存循环队列的起始地址,也可以用数组的形式,这里采用指针,后续通过malloc函数从堆中分配地址。
四. 代码清单
- CycleQueue.h
#ifndef _CYCLEQUEUE_H_
#define _CYCLEQUEUE_H_
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define ElemType int
#define MAXSIZE 11
typedef struct
{
ElemType *base; //存放基地址
int front;
int rear;
}CycleQueue;
/* 初始化队列 */
void InitQueue(CycleQueue *q);
/* 插入元素 */
void InsertQueue(CycleQueue *q,ElemType e);
/* 出列 */
void DeleteQueue(CycleQueue *q,ElemType *e);
#endif /* ----- #ifndef _CYCLEQUEUE_H_ ----- */
- CycleQueue.c
#include "CycleQueue.h"
void InitQueue(CycleQueue *q)
{
q->base = (ElemType *)malloc(MAXSIZE * sizeof(ElemType));
if(!q->base)
exit(0);
q->front = q->rear = 0;
}
void InsertQueue(CycleQueue *q,ElemType e)
{
if((q->rear+1) % MAXSIZE == q->front)
{
printf("队列已满\n");
return;
}
q->base[q->rear] = e;
q->rear = (q->rear+1) % MAXSIZE;
}
void DeleteQueue(CycleQueue *q,ElemType *e)
{
if(q->front == q->rear)
{
printf("队列为空\n");
return;
}
*e = q->base[q->front];
q->front = (q->front+1) % MAXSIZE;
}
- 随便写的一个main.c
#include "CycleQueue.h"
int main(int argc,char **argv)
{
int i,temp;
CycleQueue Que;
InitQueue(&Que);
DeleteQueue(&Que,&temp);
for(i=1; i<=10; i++)
{
InsertQueue(&Que,i);
}
for(i=1; i<=10; i++)
{
DeleteQueue(&Que,&temp);
printf("获取到元素:%d \n",temp);
}
return 0;
}
- makefile
CC = gcc
main: CycleQueue.o main.c
$(CC) main.c CycleQueue.o -o main
CycleQueue.o: CycleQueue.c
$(CC) -c CycleQueue.c
clean:
rm *.o main
~
五. 运行程序
今天的博客就写到这了,如果有错误的地方,还望指出!