队列是一端插入一端删除的数据结构,不同于栈在一端同时删除和插入
初始化后的队列ADT
但是我们可以看到此时会有一种问题就是假溢出
也就是我们入队5个元素后 将123位置的元素出列但是会发现 再次入队的话队列已经无法入队 因此我们需要引入一个循环队列的ADT
这样我们就可以只用将队列从0直接入队
但是怎样将rear游标移动到0这个位置呢?
其实只需要套用下面的公式就可以将front rear在这个环中每次逆时针向后移动一位
front=(front+1)%maxsize
rear=(rear+1)%maxsize
也就是等于他和maxsize的差距 差几个位置到一圈 加一是因为产生了一个差值
队列的顺代码实现(数组):
typedef struct
{
int front;//头元素前一个元素的下标位置
int rear; //队尾元素的下标
int maxSize;//队列的最大长度
ElemType *element;//指向一维数组
}Queue;
//创建一个能容纳maxsize个元素的空队列
void Creat(Queue *Q,int mSize)
{
Q->maxSize = mSize;
Q->element = (ElemType)malloc(sizeof(ElemType)*maxSize);
Q->front = Q->rear = 0;
}
//销毁一个存在的队列并释放内存
void Destroy(Queue *Q)
{
Q->maxSize == -1;
free(Q->element);
Q->front = Q->rear = -1;
}
//判断队列是否为空
BOOL IsEmpty(Queue *Q)
{
return Q->front = Q->rear;
}
//判断队列是否已满
BOOL IsFull(Queue *Q)
{
return (Q->rear+1)%Q->maxSize==Q->front;//在循环队列中如果rear向后移动一个和front重合
}
//获取队列头元素
BOOL Front(Queue *Q, ElemType* x)
{
if(IsEmpty(Q))
return FALSE;
x=Q->element[( Q->front+1 )% Q->maxSize];
return TRUE;
}
//在队列的队尾插入元素x
BOOL EnQueue(Queue *Q,ElemType * x)
{
if(IsFull(Q))
return FALSE;
Q->rear=(Q->rear+1)%Q->maxSize;
Q->element[Q->rear]=x;
return TRUE;
}
//删除队列的头元素
BOOL DeQueue(Queue * Q)
{
if(IsEmpty(Q))
return FALSE;
Q->front=(Q->front+1)%Q->maxSize;//巧妙的利用取余将循环队列的下标后移一个从而无视头元素
return TRUE;
}
//清楚队列的所有元素,不释放内存
void Clear(Queue *Q)
{
Q->front = Q->rear = 0;
}
如果使用顺序表的话(数组) 需要留出一个位置作为标志判断队列是否满
#include<stdlib.h>
#include<stdio.h>
#define STATE_OK 1
#define STATE_FALSE 0
#define MAX_SIZE 6
typedef int State;
/*循环队列结构*/
typedef struct {
int data[MAX_SIZE]; //这里的数据暂且作为int 可以改为class 或者 结构体
int front; //头
int rear; //尾
int length;
}SeqQueue;
void InitSeqQueue(SeqQueue * seq_queue)
{
if(seq_queue == NULL){
seq_queue = (SeqQueue *)malloc(sizeof(SeqQueue));
}
seq_queue->front = 0;
seq_queue->rear = 0;
seq_queue->length = 0;
}
State IsSeqQueueEmpty(SeqQueue * seq_queue)
{
if(seq_queue->rear == seq_queue->front)
return STATE_OK;
return STATE_FALSE;
}
State IsSeqQueueFull(SeqQueue * seq_queue)
{
if(seq_queue->rear + 1 % MAX_SIZE == seq_queue->front) //相差一位
{
return STATE_OK;
}
return STATE_FALSE;
}
State offer(SeqQueue * seq_queue,int element)
{
if(IsSeqQueueFull(seq_queue))
{
return STATE_FALSE;
}
seq_queue->data[seq_queue->rear] = element;
seq_queue->rear = (seq_queue->rear + 1) % MAX_SIZE; // 后移一位 但是要形成环状
seq_queue->length++;
return STATE_OK;
}
//尾进头出 *element记录出队数据
State poll(SeqQueue * seq_queue,int * element)
{
if(IsSeqQueueEmpty(seq_queue))
return STATE_FALSE;
*element = seq_queue->data[seq_queue->front];
seq_queue->front = (seq_queue->front + 1) % MAX_SIZE;
seq_queue->length--;
return STATE_OK;
}