九、数据结构——顺序队列中的循环队列

目录

一、循环队列的定义
二、循环队列的实现
三、循环队列的基本操作

四、循环队列的应用
五、全部代码

数据结构中的循环队列

在数据结构中,队列(Queue)是一种常见的线性数据结构,遵循先进先出(First In First Out,FIFO)的原则。循环队列是队列的一种变体,它可以更高效地利用存储空间,并解决了普通队列可能出现的假溢出问题。本篇博客将详细介绍循环队列的定义、实现和基本操作。
在这里插入图片描述

一、 循环队列的定义

循环队列是通过数组或链表实现的一种队列,它将队列的首尾相连,形成一个循环。在循环队列中,队尾指针(rear)可能在队列的前面,队头指针(front)可能在队列的后面。当队列为空时,front和rear指向同一个位置。当队列满时,front和rear之间有一个空位。

二、循环队列的实现

我们可以通过数组来实现循环队列。为了更好地利用存储空间,通常会预留一个位置来区分队列是空还是满。具体来说,我们需要定义一个固定大小的数组和两个指针front和rear来表示队头和队尾。

typedef int TypeData;
typedef struct Node{
    TypeData *data;
    int front;
    int rear;
    int len;
}Queue,*Pqueue;

三、循环队列的基本操作

①初始化队列

Pqueue init_queue(Pqueue *queue, int m){
    *queue = (Pqueue)malloc(sizeof(Queue));
    if(*queue == NULL){
        return NULL;
    }
    (*queue)->data = (TypeData *)malloc(sizeof(Queue) * m);
    (*queue)->front = (*queue)->rear= 0;
    (*queue)->len = m;
    return *queue;
}

②判空

int isEmpty(Pqueue queue){
    return queue->front == queue->rear;
}

③判满

int full(Pqueue queue){
    return (queue->rear+1) % (queue->len) == (queue->front);
}

④入队

int queue_en(Pqueue queue, TypeData value){
    if(full(queue)){
        return -1;
    }
    queue->data[queue->rear] = value;
    queue->rear = (queue->rear+ 1) % (queue->len);
    return 0;
}

⑤出队

TypeData queue_de(Pqueue queue){
    if(isEmpty(queue)){
        return -1;
    }
    TypeData temp = queue->data[queue->front];
    queue->front = (queue->front + 1) % (queue->len);
    return temp;
}

⑥获取队列长度

int get_length(Pqueue queue){
#if 0
    int a = queue->rear - queue->front;
    if(a >= 0){
        return a;
    }else{
        return (a + queue->len) % (queue->len);
    }
#else 
    return (queue->rear - queue->front + queue->len) % queue->len;
#endif
}

⑦打印

void show(Pqueue queue){
    for(int i = queue->front; i != queue->rear; i = (i + 1) % queue->len){
        printf("%d ",queue->data[i]);
    }
    printf("\n");
}

四、循环队列的应用

循环队列常用于解决生产者-消费者问题,以及在需要定期缓存数据时。它还在计算机操作系统的进程调度中得到广泛应用,用于管理就绪队列。循环队列的高效性和简单性使其成为许多问题的理想解决方案。

五、全部代码

①seqqueue.h

#ifndef _SEQQUEUE_H_
#define _SEQQUEUE_H_
#include <stdio.h>
#include <stdlib.h>

typedef int TypeData;
typedef struct Node{
    TypeData *data;
    int front;
    int tail;
    int len;
}Queue,*Pqueue;

Pqueue init_queue(Pqueue *queue, int m);

int isEmpty(Pqueue queue);

int full(Pqueue queue);

int get_length(Pqueue queue);

int queue_en(Pqueue queue, TypeData value);

TypeData queue_de(Pqueue queue);

void show(Pqueue queue);

#endif

②seqqueue.c

#include "seqqueue.h"
Pqueue init_queue(Pqueue *queue, int m){
    *queue = (Pqueue)malloc(sizeof(Queue));
    if(*queue == NULL){
        return NULL;
    }
    (*queue)->data = (TypeData *)malloc(sizeof(Queue) * m);
    (*queue)->front = (*queue)->tail = 0;
    (*queue)->len = m;
    return *queue;
}

int isEmpty(Pqueue queue){
    return queue->front == queue->tail;
}

int full(Pqueue queue){
    return (queue->tail+1) % (queue->len) == (queue->front);
}

int get_length(Pqueue queue){
#if 0
    int a = queue->tail - queue->front;
    if(a >= 0){
        return a;
    }else{
        return (a + queue->len) % (queue->len);
    }
#else 
    return (queue->tail - queue->front + queue->len) % queue->len;
#endif
}

int queue_en(Pqueue queue, TypeData value){
    if(full(queue)){
        return -1;
    }
    queue->data[queue->tail] = value;
    queue->tail = (queue->tail + 1) % (queue->len);
    return 0;
}

TypeData queue_de(Pqueue queue){
    if(isEmpty(queue)){
        return -1;
    }
    TypeData temp = queue->data[queue->front];
    queue->front = (queue->front + 1) % (queue->len);
    return temp;
}

void show(Pqueue queue){
    for(int i = queue->front; i != queue->tail; i = (i + 1) % queue->len){
        printf("%d ",queue->data[i]);
    }
    printf("\n");
}

③seqqueue_main.c

#include "seqqueue.h"
#include "seqqueue.c"
#include <unistd.h>
int main(int argc, char *argv[])
{ 
    Pqueue queue;
    init_queue(&queue, 10);

    printf("入队:");
    queue_en(queue, 20);
    queue_en(queue, 55);
    queue_en(queue, 60);
    queue_en(queue, 99);
    queue_en(queue, 22);
    queue_en(queue, 66);
    queue_en(queue, 100);
    show(queue);
    
    printf("出队:");
    queue_de(queue);

    show(queue);
    
    printf("队内还有%d个元素",get_length(queue));
    printf("\n");

    return 0;
} 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
顺序循环队列是一种使用顺序存储结构实现队列。它通过将队列的首尾相连,构成一个循环的结构,解决了普通队列在出队操作时需要移动元素的问题,提高了算法效率。[2] 顺序循环队列的结构定义如下: ```c #define SIZE 8 typedef struct Queue { int elem[SIZE]; // 存放队列元素 int front; // 队头 int rear; // 队尾 } Queue, *QueueS; ``` 其,`elem`数组用于存放队列元素,`front`表示队头的位置,`rear`表示队尾的位置。当队列为空时,`front`和`rear`的值相等;当队列满时,`rear`的下一个位置就是`front`。通过这种方式,可以实现循环利用队列的存储空间。 顺序循环队列的操作包括入队和出队操作。入队操作将元素插入到队尾,同时更新`rear`的位置;出队操作将队头元素删除,同时更新`front`的位置。当队列满时,无法进行入队操作;当队列为空时,无法进行出队操作。因此,需要额外的判断条件来判断队列是否满或为空。 顺序循环队列实现可以通过取模运算来实现循环的效果,即在计算`rear`和`front`的位置时,使用`(rear + 1) % SIZE`和`(front + 1) % SIZE`来计算新的位置。 总结来说,顺序循环队列是一种通过循环利用队列存储空间来提高算法效率的数据结构。它使用顺序存储结构实现,通过将队列的首尾相连构成循环结构,解决了普通队列在出队操作时需要移动元素的问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小羊客栈

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值