队列的定义:队列是只允许在一段进行插入操作,在另一端进行删除操作的线性表。
队列是一种先进先出(first in first out)的线性表,简称FIFO。允许插入的一段称为队尾,允许删除的一段称为队头。
队列顺序存储:
队头不需要一定在下标为0的位置。
假溢出:数组尾元素已经占用,在向后添加,就会产生数组越界的错误。
解决假溢出的方法:后面填满了就从头开始,头尾相连的循环。
循环队列:队列头尾相连的顺序存储结构
当队列空时,条件front == rear
当队列满时,保留一个元素空间,如下图。(rear +1)%QueueSize == front
取模的原因是整合rear和front大小的问题,可能相差一个位置,可能相差一圈。
当rear < front 的时候,队列长度分为两段,一段是QueueSize - front 。一段是0 + rear
所以通用的计算队列长度公式:(QueueSize - front + rear ) %QueueSize
循环队列的基本操作:
#include<iostream>
using namespace std;
#define OK 1
#define error 0
#define MAXSIZE 10 // #define预处理指令的最后加分号的话就会造成难以检查的错误
//Eg:Error :应输入];
typedef int status;
typedef int eleType;
typedef struct squeue
{
eleType data[MAXSIZE];
eleType front;
eleType rear;
}squeue;
status initSqueue(squeue* Q)
{
Q->front = 0;
Q->rear = 0;
return OK;
}
int SqueueNum(squeue* Q)
{
return (Q->rear + MAXSIZE -Q->front )%MAXSIZE;
}
status EnterSqueue(squeue* Q,eleType e)
{
if((Q->rear + 1)% MAXSIZE != Q->front)
return error;
//不是Q是类似数组 而是Q当中的data[] 所以访问的时候
//1 Q->rear 代表数组中的位置
//2 Q->data 代表要访问的数组
Q->data[Q->rear] = e;
Q->rear = (Q->rear + 1) % MAXSIZE;
return OK;
}
status DeleteSqueue(squeue* Q,eleType *e)
{
if(Q->rear == Q->front)
return error;
*e = Q->data[Q->front];
//Q->front = (Q->front - 1 )采用循环队列 并不是头指针从0位开始
//只要把队列最前面的删除就可以了
Q->front =(Q->front + 1) % MAXSIZE;
return OK;
}