什么是队列
队列是只允许在一端进行插入操作,另一端进行删除操作的线性表,
队列是一种先进先出(First In First Out)的线性表,简称FIFO。允许插入的一端为队尾,允许删除的一端称为队头。
####抽象数据类型
顺序存储队列的缺点
对于长度为n的队列, 顺序存储则需要建立 大于n的数组,队列元素存储在数组前n个元素
此时 入队操作既是在数组末尾添加元素,时间复杂度O(1)
出队操作时,a1 出队列 ,则后续元素需要前移,时间复杂度O(n)
如果不限制队列的元素必须存储在数组的前n个单元,出队性能大大增加
解决方法
引入两个指针,front指针指向队头元素,rear指针指向队尾元素的下一个位置,
front=rear时,则是空队列
依旧存在的问题,数组越界了,前边的空位还有,这种现象称作假溢出。如图入队a6越界
于是引出了循环队列
循环队列
为了解决假溢出现象,后边满了则从头开始, 也就是头尾相衔的循环。我们把这种头尾相接的顺序存储结构成为循环队列。
新的问题
前边提到空队列时候,front= rear,然而如图 当插入a7时候 front=a7
- 解决方法1
设置一个标志变量flag,当frontrear,且 flag=0时为空队列,当frontrear,且flag==1 则为队列满了 - 解决方法2
当空队列时,条件是front==rear,当队列满时,修改其条件,保留一个元素空间。也就是说,队列满时,数组中还有一个空闲单元。
方法2的讨论
若队列的最大尺寸是 QueueSize,
- 满队列公式 (rear+1)%QueueSize == front
- 队列长度公式 (rear-front+QueueSize)%QueueSize
/**
* 顺序存储 循环队列
*/
#include "stdio.h"
typedef int QEleType; //栈元素类型 此处定义为int
#define MAXSIZE 6
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status;
typedef struct {
QEleType data[MAXSIZE];
int front;
int rear;
} SqQueue;
//初始化队列
Status InitQueue(SqQueue *q){
q->front = 0;
q->rear = 0;
return OK;
}
//返回队列长度
int QueueLength(SqQueue q){
return (q.rear-q.front+MAXSIZE)%MAXSIZE;
}
//入队列
Status EnQueue(SqQueue *q, QEleType e){
//判断是否满队列
if((q->rear+1) %MAXSIZE == q->front){
return ERROR;
}
printf("来入队列了===%d\n",e);
q->data[q->rear] = e;
q->rear = (q->rear+1)%MAXSIZE;
return OK;
}
//出队列
Status DeQueue(SqQueue *q, QEleType *e){
//判断是否是空队列
if(q->rear == q->front){
return ERROR;
}
*e = q->data[q->front];
q->front = (q->front+1)%MAXSIZE;
return OK;
}
int main(){
printf("循环队列\n");
SqQueue q;
int l = InitQueue(&q);
EnQueue(&q,1);
EnQueue(&q,2);
EnQueue(&q,3);
EnQueue(&q,4);
EnQueue(&q,5);
EnQueue(&q,6);
}
队列的链式存储
/**
* 链式存储 循环队列
*/
#include "stdio.h"
typedef int QEleType; //栈元素类型 此处定义为int
#define MAXSIZE 6
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define NULL 0
typedef int Status;
//节点结构
typedef struct QNode
{
QEleType data;
struct QNode *next;
}QNode,*QueuePtr;
//队列的链表结构
typedef struct
{
QueuePtr front,rear; //队头队尾指针
} LinkQueue;
//返回队列长度
int QueueLength(LinkQueue q){
return (q.rear-q.front+MAXSIZE)%MAXSIZE;
}
//入队列
Status EnQueue(LinkQueue *q, QEleType e){
//生成结点
QueuePtr s = (QueuePtr)malloc(sizeof(QNode));
//存储分配失败
if(!s){
exit(ERROR);
}
s->data = e;
s->next = NULL;
q->rear->next = s;
q->rear = s;
return OK;
}
//出队列
Status DeQueue(LinkQueue *q, QEleType *e){
QueuePtr p;
if(q->front == q->rear){
return ERROR;
}
p = q->front->next;
*e = p->data;
q->front->next = p->next;
free(p);
return OK;
}
int main(){
}