您的位置:首页 > 其它

队列的顺序存储

2016-11-09 16:30 232 查看
队列:

插入数据:队尾(队尾的位置为空)

删除数据:队头

顺序队列:

建立一个长度为大于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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: