1.队列是什么?
- 队列遵循先进先出的规则(犹如排队买东西,先来排队的人先买到,先走。)
- 队列是只允许在表的一端进行添加,一段进行删除。(添加的表端称为表尾,删除的一端称为表头)
- 表头:指向队列中指向队列的头元素。
- 表尾:指向队列中末尾元素的下一个位置(表尾指向的位置为空)。
- 队列的存储方式:顺序存储结构,链式存储结构。
1.1顺序存储结构
#include <stdio.h>
#define SIZEMAX 10//队列的最大存储数量
#define OK 1
#define ERROR -1
typedef int Status;
typedef int Elemtype;
typedef struct
{
Elemtype *arr;
int front,rear;
}Queue;
Status InitQueue(Queue &Q)
{
Q.arr=new int[SIZEMAX];
if(!Q.arr)
{
return ERROR;
}else
{
Q.front=0;
Q.rear=0;
}
}
//入队
Status EnQueue(Queue &Q,int data)
{
if(Q.rear==SIZEMAX)//判断队列是否满
{
return ERROR;
}else
{
Q.arr[Q.rear++]=data;
}
}
//出队
Status DeQueue(Queue &Q,int &data)
{
if(Q.front==SIZEMAX)//判断队列是否空
{
return ERROR;
}else
{
data=Q.arr[Q.front++];
}
}
//判断队列是否为空
Status Empty(Queue Q)
{
if(Q.front==SIZEMAX-1)
{
return ERROR;
}else
{
return OK;
}
}
//销毁队列
Status Destroy(Queue &Q)
{
free(Q.arr);
Q.front=0;
Q.rear=0;
return OK;
}
Elemtype GetFront(Queue Q)
{
return Q.arr[Q.front];
}
上面所构造的顺序队列我们发现会浪费特别多的空间
所以就有了循环队列的出现
入队的操作如下图
出队的操作如下图
我们发现元素出对之后会有空间浪费(假溢出)
于是我们前辈便想出来的循环队列
当队列满的时候rear=(rear+1)%SIZEMAX;这样rear又重新指向队头
front=(front+1)%SIZEMAX;front也可以重新指向对头。
循环队列的代码和普通队列只是在添加和删除的时候采用了取余运算。
循环队列的出现解决了假溢出。
代码如下
#include <stdio.h>
#define SIZEMAX 10//队列的最大存储数量
#define OK 1
#define ERROR -1
typedef int Status;
typedef int Elemtype;
typedef struct
{
Elemtype *arr;//存储空间的基地址
int front,rear;
}Queue;
Status InitQueue(Queue &Q)
{
Q.arr=new int[SIZEMAX];
if(!Q.arr)
{
return ERROR;
}else
{
Q.front=0;
Q.rear=0;
}
}
//入队
Status EnQueue(Queue &Q,int data)
{
if(Q.rear==SIZEMAX)//判断队列是否满
{
return ERROR;
}else
{
Q.arr[Q.rear]=data;
Q.rear=(Q.rear+1)%SIZEMAX;
}
}
//出队
Status DeQueue(Queue &Q,int &data)
{
if(Q.front==SIZEMAX)//判断队列是否空
{
return ERROR;
}else
{
data=Q.arr[Q.front];
Q.front=(Q.front+1)%SIZEMAX;
}
}
//判断队列是否为空
Status Empty(Queue Q)
{
if(Q.front==SIZEMAX-1)
{
return ERROR;
}else
{
return OK;
}
}
//销毁队列
Status Destroy(Queue &Q)
{
free(Q.arr);
Q.front=0;
Q.rear=0;
return OK;
}
Elemtype GetFront(Queue Q)
{
return Q.arr[Q.front];
}
1.2链式队列
顾名思义采用链式存储结构实现的队列
队列遵循先进先出的规则,我们就应该使用尾插法进行创建链式队列
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR -1
typedef int Status;
typedef int Elemtype;
typedef struct _Node
{
Elemtype data;
struct _Node *next;
}Node,*PNode;
typedef struct
{
PNode rear;
PNode front;
}Queue;
Status InitQueue(Queue &Q)
{
Q.rear=Q.front=new Node;
if(!Q.rear)
{
return ERROR;
}else
{
Q.front->next=NULL;//创建一个空结点便于队列的操作
return OK;
}
}
//进队
Status Push(Queue &Q,Elemtype data)
{
PNode P=new Node;//申请内存
P->data=data;
P->next=NULL;//将新结点的next为NULL
Q.front->next=P;
Q.front=P;//新结点和front指针交换
return OK;
}
//出队,data接受出队的元素
Status Pop(Queue &Q,Elemtype &data)
{
if(Q.front->next)//队列不为空
{
PNode P=Q.front->next;//把该节点释放
Q.front->next=P->next;//把指针指向头结点的下一个的下一个的节点位置
data=P->data;
delete P;
return OK;
}else
{
return ERROR;
}
}
总结——队列
顺序队列可以看成对一个数组进行操作,能在队头和队尾进行操作。
链式队列的入队就是单链表的尾创建。链式队列就是特殊的单链表