结构-循环队列

循环队列

为什么需要循环队列?

我的理解:系统的内存一般是有边界的。像栈、链表这种数据结构的位置一般是稳定的,无非是变长变短;但是队列就不一样了,在执行入队出队的操作时,数据内存整体会呈现出一种不断向后撤的姿态,一旦它撤到内存的边界,就会出现一系列错误。

循环队列的结构设计

由于循环对列给定了数据范围的大小,则不需要使用链式的动态创建方法了(如果依旧使用链式存储,会无法确定何时再回到队头进行插入操作),因此我们采用模拟的方法。

data表示一个数据域,int为类型,其可以修改为任意自定义的类型,比如说简单的char,float类型等等,也可以是复杂的结构体类型,我们使用maxsize表示循环队列的最大容纳量,其表示队列的全部可操作空间。

rear代表尾指针,入队时移动。

front代表头指针,出队时移动。

  • rear和front说是指针,其实是一个整数,因为data是在数组中储存的,所以整数也能实现类似指针的效果。
  • 因为用的是数组,所以循环队列的大小在一开始就是规定好的。
#define maxsize 10      //表示循环队列的最大容量
  
//循环队列的结构设计
typedef struct cir_queue{
    int data[maxsize];
    int rear;
    int front;
}cir_queue;

初始化

//初始化
cir_queue *init(){
    cir_queue *q = (cir_queue*)malloc(sizeof(cir_queue));
    if(q==NULL){
        exit(0);   //申请内存失败,退出程序
    }
    q->front=0;
    q->rear=0;
    return q;
}
//让rear和front都指向第一个结点(也就是数组[0]的位置)。

操作---入队

入队操作同顺序队列的方法,直接将rear向后移动即可,但是要注意判断,如果rear达到了队列的空间上线,将要从头继续开始移动,这里推荐使用余数法,即无论如何求余都是在这片空间内进行操作,防止一次错误执行就直接整体崩溃,而且也相对而言更为简洁,不推荐使用if语句,这样显得比较累赘。

//入队操作push
void push(cir_queue *q,int data){
    if((q->rear+1)%maxsize==q->front){
        printf("溢出,无法入队\n");
        return;
    }else{
        q->rear=(q->rear+1)%maxsize;
        q->data[q->rear]=data;
    }
}
//先判断队是否是满的,再去移动。

操作---出队

//出队操作pop
void pop(cir_queue *q){
    if(q->rear==q->front){
        printf("队列为空,无法出队\n");
        return;
    }else{
        q->data[q->front]=0;
        q->front=(q->front+1)%maxsize;
    }
}

操作---遍历

//遍历队列
void print(cir_queue *q){
    int i=q->front;
    while(i!=q->rear){
        i=(i+1)%maxsize;
        printf("%d\t",q->data[i]);   
    }
    printf("\n");       //记得换行
}

完整代码

#include<stdio.h>
#include<stdlib.h>
#include<cstring>
#define maxsize 10      //表示循环队列的最大容量
 
//循环队列的结构设计
typedef struct cir_queue{
    int data[maxsize];
    int rear;
    int front;
}cir_queue;
 
//初始化
cir_queue *init(){
    cir_queue *q = (cir_queue*)malloc(sizeof(cir_queue));
    if(q==NULL){
        exit(0);    //申请内存失败,退出程序
    }
    memset(q->data,0,sizeof(q->data));
    q->front=0;
    q->rear=0;
    return q;
}
 
//入队操作push
void push(cir_queue *q,int data){
    if((q->rear+1)%maxsize==q->front){
        printf("溢出,无法入队\n");
        return;
    }else{
        q->rear=(q->rear+1)%maxsize;
        q->data[q->rear]=data;
    }
}
 
//出队操作pop
void pop(cir_queue *q){
    if(q->rear==q->front){
        printf("队列为空,无法出队\n");
        return;
    }else{
        q->data[q->front]=0;
        q->front=(q->front+1)%maxsize;
    }
}
 
//遍历队列
void print(cir_queue *q){
    int i=q->front;
    while(i!=q->rear){
        i=(i+1)%maxsize;
        printf("%d\t",q->data[i]);   
    }
    printf("\n");       //记得换行
}
 
int main(){
    cir_queue *q = init();
    ////////////入队操作///////////////
    printf("入队操作\n");
    for(int i=1;i<=6;i++){
        push(q,i);
    }
    print(q);
    ////////////出队操作///////////////
    printf("出队操作\n");
    for(int i=1;i<=3;i++){
        pop(q);
        print(q);
    }
    return 0;
}

结构-循环队列

上一篇:内部类学习


下一篇:2021-08-27目标股