循环队列

实际中我们还会用到一种队列叫做循环队列,这种队列把存储空间前后连接起来,形成像环一样的结构,解决了内存空间浪费的问题

这里我们用顺序结构来实现,因为为了防止溢出的情况,这里我们需要多开一个数据的空间用作缓冲,这部分不用于存数据,用于防止溢出,当数组访问到这一部分时就将他归零,实现循环的结构。
每次入数据通过队尾指针入,出数据通过队首指针出,和队列的操作方法差不多,每一步骤的具体实现思路会在下面写出

数据结构
typedef int DataType;
typedef struct
{DataType* queue;int front;int rear;int length;
} CircularQueue;
实现的接口
CircularQueue* CircularQueueCreate(int k);
//循环队列初始化
bool CircularQueueEnQueue(CircularQueue* obj, DataType value);
//循环队列入队
bool myCircularQueueDeQueue(CircularQueue* obj);
//循环队列出队
DataType CircularQueueFront(CircularQueue* obj);
//获取循环队列队首
DataType CircularQueueRear(CircularQueue* obj);
//获取循环队列队尾
int CircularQueueSize(CircularQueue* obj);
//循环队列长度
bool CircularQueueIsEmpty(CircularQueue* obj);
//判断循环队列是否为空
bool CircularQueueIsFull(CircularQueue* obj);
//判断循环队列是否已满
void CircularQueueFree(CircularQueue* obj);
//销毁循环队列

循环队列初始化

CircularQueue* CircularQueueCreate(int k)
{CircularQueue* cq = (CircularQueue*)malloc(sizeof(CircularQueue));cq->queue = (DataType*)malloc((k + 1) * sizeof(DataType));cq->front = 0;cq->rear = 0;cq->length = k + 1;return cq;
}

初始化时多开一个空间,防止溢出。

入队列

bool CircularQueueEnQueue(CircularQueue* obj, DataType value)
{if ((obj->rear + 1) % obj->length == obj->front)return false;obj->queue[obj->rear++] = value;if (obj->rear == obj->length)obj->rear = 0;return true;
}

我们首先要判断队列是否已满,如果满了则返回false,为什么使用这个公式我会在下面的判断队满的函数中写到,没满则将数据存到队尾指针的位置,如果队尾指针达到了我们多开的那个位置,则让队尾指针归零

出队列

bool myCircularQueueDeQueue(CircularQueue* obj)
{if (obj->front == obj->rear)return false;;++obj->front;if (obj->front == obj->length)obj->front = 0;return true;
}

首先判断是否队空,然后使队头指针走一步,当队头指针到达多开的空间时,归零

获取队首元素

DataType CircularQueueFront(CircularQueue* obj)
{if (obj->front == obj->rear)return -1;elsereturn obj->queue[obj->front];
}

获取队尾元素

DataType CircularQueueRear(CircularQueue* obj)
{if (obj->front == obj->rear)return -1;else if (obj->rear == 0)return obj->queue[obj->length - 1];elsereturn obj->queue[obj->rear - 1];
}

获取队列中有效元素个数

int CircularQueueSize(CircularQueue* obj)
{return (obj->rear - obj -> front + obj->length) % obj->length;
}

首先用队尾位置减去队首位置,然后因为是循环队列,位置不断变化可能会出现负数和得不到正确的结果,我们就需要先加上总长度在对总长度取模,这样得到的才是他们真正的位置差,也就是有效元素个数

检测循环队列是否为空

bool CircularQueueIsEmpty(CircularQueue* obj)
{if (obj->rear == obj->front)return true;elsereturn false;
}

当队首和队尾处于同一位置时说明循环队列为空,因为此时他们的相对位置为零

检测循环队列是否已满

bool CircularQueueIsFull(CircularQueue* obj)
{if ((obj->rear + 1) % obj->length == obj->front)return true;elsereturn false;
}

当队满的时候队首应该在队尾的下一个位置,但因为循环队列位置不断变化,可能出现超过总长度或者归零的情况,所以我们需要对总长度取模来获取他们的相对位置

销毁循环队列

void CircularQueueFree(CircularQueue* obj)
{free(obj->queue);obj->queue = NULL;free(obj);obj = NULL;
}

完整代码
头文件

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef int DataType;
typedef struct {DataType* queue;int front;int rear;int length;
} CircularQueue;CircularQueue* CircularQueueCreate(int k);
//循环队列初始化
bool CircularQueueEnQueue(CircularQueue* obj, DataType value);
//循环队列入队
bool myCircularQueueDeQueue(CircularQueue* obj);
//循环队列出队
DataType CircularQueueFront(CircularQueue* obj);
//获取循环队列队首
DataType CircularQueueRear(CircularQueue* obj);
//获取循环队列队尾
bool CircularQueueIsEmpty(CircularQueue* obj);
//判断循环队列是否为空
bool CircularQueueIsFull(CircularQueue* obj);
//判断循环队列是否已满
void CircularQueueFree(CircularQueue* obj);
//销毁循环队列

函数实现

#pragma once
#include "CircularQueue.h"CircularQueue* CircularQueueCreate(int k)
{CircularQueue* cq = (CircularQueue*)malloc(sizeof(CircularQueue));cq->queue = (DataType*)malloc((k + 1) * sizeof(DataType));cq->front = 0;cq->rear = 0;cq->length = k + 1;return cq;
}bool CircularQueueEnQueue(CircularQueue* obj, DataType value)
{if ((obj->rear + 1) % obj->length == obj->front)return false;obj->queue[obj->rear++] = value;if (obj->rear == obj->length)obj->rear = 0;return true;
}bool myCircularQueueDeQueue(CircularQueue* obj)
{if (obj->front == obj->rear)return false;;++obj->front;if (obj->front == obj->length)obj->front = 0;return true;
}DataType CircularQueueFront(CircularQueue* obj)
{if (obj->front == obj->rear)return -1;elsereturn obj->queue[obj->front];
}DataType CircularQueueRear(CircularQueue* obj)
{if (obj->front == obj->rear)return -1;else if (obj->rear == 0)return obj->queue[obj->length - 1];elsereturn obj->queue[obj->rear - 1];
}bool CircularQueueIsEmpty(CircularQueue* obj)
{if (obj->rear == obj->front)return true;elsereturn false;
}bool CircularQueueIsFull(CircularQueue* obj)
{if ((obj->rear + 1) % obj->length == obj->front)return true;elsereturn false;
}void CircularQueueFree(CircularQueue* obj)
{free(obj->queue);obj->queue = NULL;free(obj);obj = NULL;
}

数据结构与算法 | 循环队列相关推荐

  1. 数据结构与算法_03队列

    数据结构与算法_03队列 队列 0.章节重点整理 1.认识队列 1.1. 队列的工作运算 1.2.队列的数组实现 1.3.队列的链表实现 2.队列的应用 2.1.环形队列 2.2.双向队列 队列 0. ...

  2. java数据结构 队列_Java数据结构与算法[原创]——队列

    声明:码字不易,转载请注明出处,欢迎文章下方讨论交流. 前言:Java数据结构与算法专题会不定时更新,欢迎各位读者监督.本文介绍数据结构中的队列(queue)的概念.存储结构.队列的特点,文末给出ja ...

  3. abcde依次进入一个队列_数据结构与算法(6):队列

    (文中图片出自王争老师的课程:数据结构与算法之美,侵删) 先进者先出,这就是典型的队列. 根据上篇文章,我们知道栈只支持两个基本操作:入栈 push()和出栈 pop().队列跟栈非常相似,支持的操作 ...

  4. JavaScript 数据结构与算法(队列)

    队列数据结构 队列是遵循先进先出(FIFO,也称为先来先服务)原则的一组有序的项.队列在尾部添加新元素,并从顶部移除元素.最新添加的元素必须排在队列的末尾.在现实中,最常见的队列的例子就是排队. 创建 ...

  5. 数据结构与算法:队列——02

    文章目录 三.队列 1.队列概述: 2.单向队列[数组表现形式]: 3.环形队列[数组表现形式]: 三.队列 1.队列概述: 定义: 队列定义 队列简称队,它也是一种操作受限的线性表.其限制为仅允许在 ...

  6. python实现队列_用Python实现的数据结构与算法:队列

    一.概述 队列(Queue)是一种先进先出(FIFO)的线性数据结构,插入操作在队尾(rear)进行,删除操作在队首(front)进行. 二.ADT 队列ADT(抽象数据类型)一般提供以下接口: Qu ...

  7. 数据结构与算法之-----队列(Queue)

    [ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己构建的,未使用 ...

  8. 三星手机电池循环清零代码_数据结构(C语言)-循环队列基本操作

    队列是一种先进先出(first in first out,FIFO)的线性表,是一种常用的数据结构. 它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列 ...

  9. 数据结构(c/c++)—循环队列的判断空满方式

    文章目录 前言 队列的数据结构 初始化 一.舍弃空间 二.不舍弃空间 1.计数器 2.设置标志位 前言 我们这里一共三个方法,通过是否舍弃空间来实现队列空满的判断. 队列的数据结构 const int ...

最新文章

  1. Java知识点:条件编译
  2. python报错:ModuleNotFoundError: No module named cv2.cv2(bug不能加英文引号)
  3. Navicat远程连接linux下mysql服务器1045错误解决办法在这儿
  4. sql server 自定义函数的使用
  5. java-图像的几何变换
  6. 设计模式 C++装饰模式
  7. Spring Boot中的事务管理与手把手实战
  8. 以太网测试仪的RFC2544测试你了解吗?
  9. 程序员为什么要转行项目经理
  10. Eclipse中Folder和SourceFolder
  11. 拆解大数据总线平台DBus的系统架构
  12. flask 数据库迁移migration
  13. 用verilog 蜂鸣器的演奏乐曲
  14. css 手风琴_如何创建基于CSS的内容手风琴
  15. 一口气了解【2021 阿里云峰会】重磅发布
  16. 北京交通大学计算机博士导师,董平(北京交通大学教授、博士生导师)_百度百科...
  17. uniapp 收藏功能实现及组件封装
  18. 单片机硬件和软件延时是啥意思?
  19. JAVA插入数据库时java.sql.DataTruncation: Data truncation
  20. 企业级自动化运维平台

热门文章

  1. 格式化输出浮点型变量
  2. Tomcat集群快速入门
  3. spring配置详解-初始化销毁方法
  4. 原型共享数据 原型简单语法 原型中方法是可以相互访问 实例对象属性方法层层搜索
  5. zabbix监控mysql的性能_zabbix2.4.2实战监控mysql5.6性能
  6. delete 会不会锁表_MySQL的insert into select 引发锁表
  7. 200726C的数据传递方式
  8. 0619-dedeCMS的安装、重装、目录说明、基本操作及注意事项
  9. CodeForces - 1454F Array Partition(线段树+二分)
  10. CodeForces - 1312E Array Shrinking(区间dp)