考研一轮循环队列顺序存储完全实现并测试(王卓版本)

在普通的队列中很容易出现假溢出的情况,为了防止假溢出,就会有循环队列。循环队列最显眼的特征就是有一个%操作,下面就以书上的常用操作集合,并给出完整的测试样例。

1、循环队列顺序存储结构

在循环队列的顺序存储的时候,基地址是一个指针可以动态分配内存,并且有头指针和尾指针。

typedef struct{
    
    
    QElemType *base;//动态分配存储空间
    int front;//头指针,若队列不空,指向队头元素
    int rear;//尾指针,若队列不空,指向队尾元素的下一个位置
}SqQueue;

2、初始化队列

初始化队列步骤如下:

  • 分配内存,并检验内存分配是否成功?
  • 头指针与尾巴指针都为0,
  • 返回OK
 Status InitQueue(SqQueue &Q){
    
    
    Q.base = new QElemType[MAXQSIZE];//分配数组空间
    //Q.base = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
    if(!Q.base) exit(OVERFLOW);//存储分配失败
    Q.front =  Q.rear = 0;//头指针尾指针置为0,队列为空
    return OK;
}

3、判定队列是否为空

头指针与尾巴指针同时指向是否为0,

 Status IsEmpty(SqQueue Q){
    
    
    if(Q.front == Q.rear) return TRUE;
    else return FALSE;
}

4、判定队列是否满了

在循环队列中,判定是否满了,就是尾指针加1与队列的容量取模,如果与头指针相等那么就满了

Status IsFull(SqQueue Q){
    
    
     if((Q.rear+1)%MAXQSIZE == Q.front) return TRUE;
     else return FALSE;
 }

5、入队

入队首先判定队列是否满了,满了返回error,入队在队尾,所以是rear

  • 判定是否满了
  • 队尾赋值
  • 队尾指针++
 Status EnQueue(SqQueue &Q,QElemType e){
    
    
     if(IsFull(Q)) return ERROR; //队列满
     Q.base[Q.rear] = e;
     Q.rear = (Q.rear+1)%MAXQSIZE;
     return OK;
 }

6、出队

出队的话,是队头出队,所以要判定队是否空。

 Status DeQueue(SqQueue &Q,QElemType &e){
    
    
     if(IsEmpty(Q)) return ERROR;//队空
     e = Q.base[Q.front];   //保存队头元素
     Q.front = (Q.front+1)%MAXQSIZE;//队头指针+1
     return OK;
 }

7、求队列的长度

尾指针与头指针的差值

int QueueLength(SqQueue Q){
    
    
     return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
 }

8、获得队列的首元素

在判断队列是否为空的前提下,front返回出去,

 QElemType GetHead(SqQueue Q){
    
    
     if(!IsEmpty(Q)){
    
    //队列不为空
         return Q.base[Q.front];//返回队头指针元素的值,队头指针不变。
     }
 }

测试效果

在这里插入图片描述

完整代码

#include<iostream>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXQSIZE 10
using namespace std;
typedef int Status;
typedef int QElemType;

typedef struct{
    
    
    QElemType *base;//动态分配存储空间
    int front;//头指针,若队列不空,指向队头元素
    int rear;//尾指针,若队列不空,指向队尾元素的下一个位置
}SqQueue;

//队列初始化
 Status InitQueue(SqQueue &Q){
    
    
    Q.base = new QElemType[MAXQSIZE];//分配数组空间
    //Q.base = (QElemType*)malloc(MAXQSIZE*sizeof(QElemType));
    if(!Q.base) exit(OVERFLOW);//存储分配失败
    Q.front =  Q.rear = 0;//头指针尾指针置为0,队列为空
    return OK;
}

int QueueLength(SqQueue Q){
    
    
     return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;
 }
//队列判定是否为空
 Status IsEmpty(SqQueue Q){
    
    
    if(Q.front == Q.rear) return TRUE;
    else return FALSE;
}
//队列判定是否满
Status IsFull(SqQueue Q){
    
    
     if((Q.rear+1)%MAXQSIZE == Q.front) return TRUE;
     else return FALSE;
 }
 //入队循环队列入队
 Status EnQueue(SqQueue &Q,QElemType e){
    
    
     if(IsFull(Q)) return ERROR; //队列满
     Q.base[Q.rear] = e;
     Q.rear = (Q.rear+1)%MAXQSIZE;
     return OK;
 }
 //base[0]接在base[MAXQSIZE-1]之后,若rear+1==M,则令rear=0
 Status DeQueue(SqQueue &Q,QElemType &e){
    
    
     if(IsEmpty(Q)) return ERROR;//队空
     e = Q.base[Q.front];   //保存队头元素
     Q.front = (Q.front+1)%MAXQSIZE;//队头指针+1
     return OK;
 }

 //取队头元素
 QElemType GetHead(SqQueue Q){
    
    
     if(!IsEmpty(Q)){
    
    //队列不为空
         return Q.base[Q.front];//返回队头指针元素的值,队头指针不变。
     }
 }

int main(){
    
    
    SqQueue Q;
    InitQueue(Q);
    cout << "after init,Is  Queue empty? 1 represent yes:" << IsEmpty(Q) << endl;
    for(int i=0;i<5;i++){
    
    
        EnQueue(Q,i+1);
    }
    cout << "queue length:" << QueueLength(Q) << endl;
    cout << "After enqueue,Is Queue full?1 represent yes:" << IsFull(Q) << endl;
    cout << "get queue head value: " << GetHead(Q) << endl;
    QElemType  e;
    DeQueue(Q,e);
    cout << "delete 1 queue value: " << e << endl;
    cout << "queue length:" << QueueLength(Q) << endl;
    return 0;

}

猜你喜欢

转载自blog.csdn.net/m0_37149062/article/details/123447109