数据结构(三)--循环队列

本文深入浅出地介绍了循环队列的基本概念与实现细节,重点解析了循环队列中入队、出队、判断队列是否为空及是否为满的具体操作,并通过示例代码展示了其在实际应用中的工作流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

循环队列的基本操作

刚把数据结构里面的队列学习了一下,主要是对循环队列的基本操作进行了了解,主要是想明白,循环队列的循环是咋实现的,就好了,然后把入队和出队,判断是否是空,和判断是否为满的弄懂就搞清楚循环队列了。

队列

这里写图片描述
如图所示,队列是一种可以实现“先进先出”的存储结构,哪一个节点元素先进来,它最先出去,然后如果想继续加入节点,就在队伍的最后面加入。
队列分为链式队列(用链表实现的)和静态队列(也就是循环队列),在这篇博客里主要讲的是循环队列的基本操作。

循环队列

这里写图片描述
循环队列是靠数组来实现的,就是如图所示一样的哈,想一条蛇,收尾相连,具体如何收尾相连,就是靠很简单的取余来实现的哈,对数组的长度进行取余,就可以循环了哈。//如果这里不懂,看下面,继续讲解的哈。

参数font/rear

在好多书上讲的是font是指向队头,rear是指向队尾,但是这个操作起来不方便。下面分情况讨论
1.队列初始化
font和rear都为0//不懂的看上图
2.队列非空的时候(就是放值的时候)
font是队列第一个元素
rear为队列最后一个有效元素的下一个元素//这样好操作
3.队列为空
这个判断起来很简单
当font和rear相等的时候,但不一定为0

定义的结构体

typedef struct  Queue{
    int *pBase;
   //这个是用来当定义的数组的首地址的
    int front;
     //队头数组的下标
    int rear;
      //队列最后一个有效元素的下一个元素的下标
}QUEUE,*PQUEUE;

初始化

先创建好数组空间
然后初始化font和rear都为0
下面这个是创了一个6个int类型元素的数组,首地址为pQ->pBase

void init(PQUEUE pQ){
    pQ->pBase = (int *)malloc(sizeof(int)*6);
    pQ->front = 0;
    pQ->rear  = 0;
}

判断循环队列是否为满

判断循环队列是否为满有2种使用的方法
1.加个参数,记录有效节点数,入队就+1,出对就-1,判断是否为满,就看它是否和创建的数组最大元素个数是否相同,但是不建议用这个方法,因为你还要重新开辟空间

2.浪费一个空间,数组只能放(n-1)个元素,一开始font和rear相同,不断入队,rear就在圈上往上走,当它快走一圈的时候,也就是rear紧挨这个font
就是当(rear+1)%数组的长度==front的时候
满了

bool full_queue(PQUEUE pQ){
    if((pQ->rear +1)%6 == pQ->front){
        return true;
    }else{
        return false;
    }
}

判断是否为空

这个最简单,就是他们font和rear相等的时候

bool out_queue(QUEUE*pQ,int *pVal){
    if(empty_queue(pQ)){
        return false;
    }else{
        *pVal = pQ->pBase[pQ->front];
        pQ->front = pQ->front+1;

    }
}

入队

先判断下队列是否为满
如果不满的话,入队
很简单,把元素放在rear的位置就好了(之前定义说过,rear为队列最后一个有效元素的下一个元素)
然后 rear=rear+1//这个不准确
又因为是循环队列哈
真正的 rear = (rear+1)%数组的长度

bool en_queue(PQUEUE pQ,int val){
    if(full_queue(pQ)){
        return false;
    }else{
        pQ->pBase[pQ->rear] = val;
        pQ->rear = (pQ->rear+1) % 6;
        returnt
ue;
    }
}

出队

先判断队列是否为空
如果是空的话就不出队了
出队的话也很简单
就是把font=font+1//这个不准确
因为是循环的哈,所以font = (font+1)%数组长度,,在这个函数里,我还把出队的元素记录了下来

bool out_queue(QUEUE*pQ,int *pVal){
    if(empty_queue(pQ)){
        return false;
    }else{
        *pVal = pQ->pBase[pQ->front];
        pQ->front = pQ->front+`
;

    }
}

总的代码

这个循环队列只是我定义为int类型的数组,里面有6个元素,这个可以自己修改,在初始化那块改的

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
/*队列的基本运用
  所有和时间的操作都和队列有关

*/
typedef struct  Queue{
    int *pBase;
    int front;
    int rear;
}QUEUE,*PQUEUE;

void init(PQUEUE);
bool en_queue(PQUEUE,int);
void traverse_queue(PQUEUE); 
bool full_queue(PQUEUE);
bool out_queue(PQUEUE,int *);
bool empty_queue(PQUEUE); 

bool empty_queue(PQUEUE pQ){
    if(pQ->front ==pQ->rear){
        return true;
    }else{
        return false;
    }
}
bool out_queue(QUEUE*pQ,int *pVal){
    if(empty_queue(pQ)){
        return false;
    }else{
        *pVal = pQ->pBase[pQ->front];
        pQ->front = pQ->front+1;

    }
}
bool full_queue(PQUEUE pQ){
    if((pQ->rear +1)%6 == pQ->front){
        return true;
    }else{
        return false;
    }
}

void init(PQUEUE pQ){
    pQ->pBase = (int *)malloc(sizeof(int)*6);
    pQ->front = 0;
    pQ->rear  = 0;
}

bool en_queue(PQUEUE pQ,int val){
    if(full_queue(pQ)){
        return false;
    }else{
        pQ->pBase[pQ->rear] = val;
        pQ->rear = (pQ->rear+1) % 6;
        return true;
    }
}
void traverse_queue(PQUEUE pQ){
    int i = pQ->front;
    while(i!=pQ->rear){
        printf("%d ",pQ->pBase[i]);
        i  = (i+1)%6;
    }
}
int main(void){
    QUEUE Q;
    int val;
    init(&Q);
    en_queue(&Q,1);
    en_queue(&Q,2);
    en_queue(&Q,3);
    en_queue(&Q,4);
    en_queue(&Q,5);
    en_queue(&Q,6);
    en_queue(&Q,7);
    en_queue(&Q,8);
    traverse_queue(&Q);
    if(out_queue(&Q,&val)){
        printf("出队 %d\n",val);
    }else{
        printf("失败\n");
    }
    traverse_queue(&Q);
    return 0;
} 

总结

这个循环队列,只要理解循环是咋弄的就很简单了哈

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值