队列类似线性表和栈,也是定义在线性结构上的ADT,与线性表和栈的区别在于,元素的插入和删除分别在表的两端进行。
类似日常生活中排队,允许插入的一端为队尾(rear),允许删除端称队头(front)
First In First Out先进先出,如操作系统中的作业队列和打印任务队列、日常生活中各类排队业务等均可用队列模拟
#include<iostream>
using namespace std;
typedef int Status;
typedef int QElemType;
#define OK 1
#define OVERFLOW -2
#define ERROR 0
1、链式存储结构定义
typedef struct QNode{
QElemType data;
struct QNode *next;
}QNode,*QueuePtr;
typedef struct {
QueuePtr front;//队头指针
QueuePtr rear;//队尾指针
}LinkQueue;//链队列
2、链队列的初始化
Status InitQueue(LinkQueue &Q){
Q.front=Q.rear=(QNode*)malloc(sizeof(QNode));
if(!Q.front) exit(OVERFLOW);
Q.front->next=NULL;
return OK;
}
3、销毁清空队列
Status DestroyQueue(LinkQueue &Q){
//销毁队列
QNode*p=Q.front,*postp;
while(p){
postp=p->next;free(p);
p=postp;
}
Q.front=NULL;Q.rear=NULL; //防止内存泄漏
return OK;
} //清空的话 需要保存头节点 并让Q.rear指向头节点
4、入队
Status EnQueue(LinkQueue &Q,QElemType e){
//插入元素e为Q的新队尾元素
QueuePtr p;
p=(QNode*)malloc(sizeof(QNode));
if(!p) exit(OVERFLOW);
p->data=e;p->next=NULL;
Q.rear->next=p;
Q.rear=p;//再次让rear指向尾指针
return OK;
}
5、出队
Status DeQueue(LinkQueue &Q,QElemType &e){
//若队列不空,则删除Q的队头元素,用e返回其值
if(Q.front==Q.rear) return ERROR;
//链队列是头节点为空的链表
QNode *p;
p=Q.front->next;
e=p->data;
Q.front->next=p->next;
if(p==Q.rear) Q.rear=Q.front;//当链队列中只有一个结点
free(p);
return OK;
}
顺序队列
Q.front与Q.rear是int,删除队头不移动数据,直接Q.front++,
typedef int QElemType;
typedef int Status;
#define MAXQSIZE 100//最大队列长度
#define OVERFLOW -2
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
顺式的存储结构定义
typedef struct{
QELemType *base;//动态分配存储空间
int front;//头指针,队列不空则指向队列头元素
int rear;//尾指针,队列不空则指向队尾元素下一个位置
}SqQueue;
1、初始化
Status InitQueue(SqQueue &Q){
Q.base=(QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
if(!Q.base) exit(OVERFLOW);
Q.rear=Q.front=0;
return OK;
}
2、销毁和清空
Status DestroyQueue(SqQueue &Q){
//销毁队列
free(Q.base);//释放基址
Q.front=Q.rear=0;
return OK;
}
Status ClearQueue(SqQueue &Q){
//队列置空
Q.front=Q.rear=0;
return OK;
}
3、插入
Status 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;//防止越界,取余
return OK;
}
4、求队长
int QueueLength(SqQueue Q){
return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;//防止为负数
}
5、判断队空
Status QueueEmpty(SqQueue Q){
if(Q.front==Q.rear) return TRUE;
else return FALSE;
}
6、求首元素
Status GetHead(SqQueue Q,QElemType &e){
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
return OK;
}
7、删除
Status DeQueue(SqQueue &Q,ElemType &e){
//把删除的队头元素赋给e带回
//检查是否为空
if(Q.front==Q.rear) return ERROR;
e=Q.base[Q.front];
Q.front=(Q.front+1)%MAXQSIZE;
return OK;
}