队列的概念
队列:只允许在一端进行插入操作,在另一端进行删除操作的线性表。
特点:先进先出。
队列与栈一样,存在顺序存储与链式存储。
循环队列
队列顺序存储容易造成假溢出,所以一般将它头尾相接,即循环队列。
队空:即 头指针(front)== 尾指针(rear)
队满:即(rear+1)%(Maxqsize 最大尺寸) == front
队长:即(Maxqsize - front + rear)%Maxqsize
循环队列的定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define Maxqsize 100
typedef int QElemType;
typedef struct {
QElemType* base; //动态分配存储空间
int front; //头指针
int rear; //尾指针
}SqQueue;
初始化循环队列
/* 初始化循环队列 */
int InitQueue(SqQueue* Q)
{
Q->base = (QElemType*)malloc(Maxqsize*sizeof(QElemType));
if (!Q->base) exit(-1);
Q->front = Q->rear = 0; 头指针与尾指针都为0
return OK;
}
求队列长度
/* 求队列长度 */
int QuenLength(SqQueue Q)
{
return ((Q.rear-Q.front+ Maxqsize)% Maxqsize) ;
}
循环队列入队
/* 循环队列入队 */
int EnQueue(SqQueue* Q, QElemType e)
{
if ((Q->rear + 1) % Maxqsize == Q->front) //队满
return ERROR;
Q->base[Q->rear] = e;
Q->rear = (Q->rear + 1) % Maxqsize; //队尾指针 + 1
return OK;
}
循环队列出队
/* 循环队列出队 */
int DeQueue(SqQueue* Q, QElemType* e)
{
if (Q->front == Q->rear) return ERROR;
*e = Q->base[Q->front];
Q->front = (Q->front + 1) % Maxqsize; //队头指针 + 1
return OK;
}
链队
如果无法预料队列长度,宜用链队。
链队大多数操作与单链表类似,下面我将举出链表的初始化、入队与出队。
空队:头指针与尾指针都指向头结点。
链队的定义
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int QElemType;
typedef struct Qnode {
QElemType data;
struct Qnode* next;
}Qnode;
typedef struct Qnode* QuenePtr;
typedef struct {
QuenePtr front; //头指针
QuenePtr rear; //尾指针
}LinkQueue;
链队初始化
/* 链队初始化 */
int InitQueue(LinkQueue* Q)
{
Q->front = Q->rear = (QuenePtr)malloc(sizeof(Qnode));//头指针与尾指针都指向头结点
if (!Q->front) exit(-1);
Q->front->next = NULL;
return OK;
}
链队的入队
/* 链队的入队 */
int EnQueue(LinkQueue* Q, QElemType e)
{
QuenePtr p = (QuenePtr)malloc(sizeof(Qnode));
if (!p) exit(-1);
p->data = e;
p->next = NULL;
Q->rear->next = p; //新节点 赋给 原队尾结点的 next
Q->rear = p; //p为新的尾结点
return OK;
}
链队的出队
/* 链队的出队 */
int DeQueue(LinkQueue* Q, QElemType* e)
{
if (Q->front == Q->rear) //如果空队
return ERROR;
QuenePtr p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p) //如果队头就是队尾
Q->rear = Q->front; //将尾结点指向头结点
free(p);
return OK;
}