队列:
插入数据:队尾(队尾的位置为空)
删除数据:队头
顺序队列:
建立一个长度为大于n的数组,把队列的所有元素存储在数组的前n个单元上,数组下标为0的一端为队头
入队操作即在队尾插入一个元素,时间复杂度为0(n)
出队操作在对头,由于固定下标为0的位置为队头,当出队列时,需要队列中的所有元素都要向前移动。
改进1
不去限制队列中的元素必须存储在数组的前n个单元,即<font color=red>队头不一定是下标为0的位置</font>
为了避免当只有一个元素时,队头和对尾的处理变得麻烦,所以引入两个指针。
front指向队头,rear指向队尾,若front=rear时,不是满队就是空队
但是还是存在问题:
假溢出:
改进2:
循环队列:
解决假溢出的问题,当后面的位置满了,从头开始。队列的这种头尾相接的顺序存储结构成为循环队列。
新问题:无法确定队列是空还是满
办法1:设置一个flag,当flag==0 && rear==front,为空
当flag==1 && rear==front 为满
办法2:在队列满时,数组中还剩一个位置。
由于是循环的操作,rear可能大于front也可能小于front
如图
判断队列的状态为:
队满的条件:
左图为rear大于front,队满的条件是(rear+1)%QueueSize== front
右图为rear小于front,队满的条件是(rear+1)==front
综上:队满的条件是:(rear+1)%QueueSize== front
队空的条件:
rear == front
队列长度的计算:
当rear大于front时,长度等于 rear-front
当rear小于front时,(证明又循环了)长度等于MAXSIZE-front的下标
加上 rear的下标+0,就等于MAXSIZE+rear-front
综上:队长的公式为:(rear-front+QueueSize)%QueueSize
代码实现:
#include <iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define MAXSIZE 20 /* 存储空间初始分配量 */
typedef int Status;
typedef int QElemType;
typedef struct{
QElemType data[MAXSIZE];
int front ; //头指针
int rear ; //尾指针 指向空的位置
}SqQueue;
Status InitQueue(SqQueue *Q){
Q->front = 0;
Q->rear = 0;
return OK;
}
Status EnQueue(SqQueue *Q,QElemType e){
if((Q->rear+1)%MAXSIZE == Q->front) //包含两种情况,rear<front 差一个位置队满
//rear>front 差一圈(一个MAXSIZE)队满
return ERROR;
Q->data[Q->rear] = e;
Q->rear = (Q->rear+1)%MAXSIZE; //当数组中后面的位置栈满,从头开始
return OK;
}
Status DeQueue(SqQueue *Q,QElemType *e){
if(Q->front == Q->rear) //队空的判断
return ERROR;
*e = Q->data[Q->front];
Q->front = (Q->front+1)%MAXSIZE; //移动到数组最后位置,从头开始
return OK;
}
int QueueLength(SqQueue Q){
return (Q.rear+MAXSIZE-Q.front)%MAXSIZE;
}
Status GetHead(SqQueue q,QElemType *e){
if(q.front == q.rear) //队列为空
return ERROR;
*e = q.data[q.front];
return OK;
}
int main()
{
SqQueue q ;
InitQueue(&q);
for(int i=0;i<10;i++){
EnQueue(&q,i);
}
printf("元素进队列的顺序为\n");
for(int i=0;i<10;i++){
printf("%d\n",q.data[i]);
}
printf("队列的元素个数为%d\n",QueueLength(q));
int value ;
GetHead(q,&value);
printf("队列的head的值为%d\n",value);
printf("元素出队列的顺序为\n");
int result;
for(int i=0;;i++){
if(q.front == q.rear)
break;
DeQueue(&q,&result);
printf("%d\n",result);
}
return 0;
}