数据结构第九弹---循环队列

循环队列

  • 1、循环队列的定义
  • 2、循环队列的结构
  • 3、循环队列的实现
    • 3.1、初始化队列
    • 3.2、判断是否为空
    • 3.3、判断是否为满
    • 3.4、入队
    • 3.5、出队
    • 3.6、返回队头元素
    • 3.7、返回队尾元素
    • 3.8、销毁队列
  • 4、代码汇总
  • 总结

1、循环队列的定义

顺序队列在使用过程中容易出现虚假的满状态, 为了解决这个问题,就产生了一个较巧妙的方法,将顺序队列臆造为一个环状的空间,称之为循环队列。循环队列中指针和队列元素之间的关系不变,我们只需要利用模运算就可以很容易实现指针的循环移动。但是循环队列中存在一个问题,在循环队列中只凭头指针front等于尾指针rear无法判别队列空间是“空”还是“满”,可有两种处理方法:其一是另设一个标志位以区别队列是“空”还是“满”;其二是少用一个元素空间,约定以“队列头指针在队列尾指针的下一位置(指环状的下一位置)上”作为队列呈“满”状态的标志。此处使用方法二来解决这个问题。

2、循环队列的结构

在这里插入图片描述

在这里插入图片描述

typedef struct CircularQueue{int* a;//存放数据数组int front;//头结点int back;//尾结点后一个,有效数据个数int k;//元素个数
} CircularQueue;

3、循环队列的实现

3.1、初始化队列

开辟k+1个空间,k个存放数据,将头尾结点初始化为0,即数组的第一个位置。

在这里插入图片描述
代码实现

//队列初始化
CircularQueue* InitQueue(int k)
{CircularQueue* obj=(CircularQueue*)malloc(sizeof(CircularQueue));//为队列分配空间obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->back=0;//初始队列为空,头尾指针都指向0的位置obj->k=k;return obj;
}

测试
在这里插入图片描述

3.2、判断是否为空

根据结构定义,头结点跟尾结点相等时则队列为空。为真则为空,为假则不为空。

代码实现

bool QueueEmpty(CircularQueue* obj) {return obj->front==obj->back;//头尾结点相等时则为空
}

测试
在这里插入图片描述

3.3、判断是否为满

根据循环队列结构的定义,尾结点后一个是头结点则队列为满。为真则为满,不为真则不满。

在这里插入图片描述
代码实现


bool QueueFull(CircularQueue* obj) {return (obj->back+1)%(obj->k+1)==obj->front;//尾结点的下一个等于头结点则为满
}

测试
在这里插入图片描述

3.4、入队

根据队列的结构定义,back为尾结点的后一个,当队列空间没有满时,插入数据时则在back位置插入。
在这里插入图片描述
代码实现


bool EnQueue(CircularQueue* obj, int value) {//满了返回falseif(QueueFull(obj)){return false;}obj->a[obj->back]=value;//插入有效数据obj->back++;obj->back%=(obj->k+1);//进入循环,不能超过最大个数return true;
}

测试
在这里插入图片描述

3.5、出队

根据队列的定义,只能队头出数据,在循环队列里面通过头尾结点来访问数据,将front++即可删除头结点数据。

在这里插入图片描述
代码实现


bool DeQueue(CircularQueue* obj) {//如果为空返回falseif(QueueEmpty(obj)){return false;}obj->front++;//出队则头结点往前走obj->front%=(obj->k+1);return true;
}

测试
在这里插入图片描述

3.6、返回队头元素

在保证队列不是空的情况下,队头元素为front下标的元素,为空则返回-1

代码实现


int QueueFront(CircularQueue* obj) {//为空返回-1if(QueueEmpty(obj))return -1;return obj->a[obj->front];
}

测试
在这里插入图片描述

3.7、返回队尾元素

在保证队列不是空的情况下,队头元素为back前一个下标的元素,为空则返回-1

在这里插入图片描述
代码实现

int QueueRear(CircularQueue* obj) {//为空返回-1if(QueueEmpty(obj))return -1;//有一种特殊情况 不是back-1//1.//return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];return obj->a[(obj->back+obj->k)%(obj->k+1)];//2.// if(obj->back==0)// {//     return obj->a[obj->k];// }// else// {//     return obj->a[obj->back-1];// }
}

测试
在这里插入图片描述

3.8、销毁队列

数组是通过队列的指针访问,且数组和队列都是内存是连续的,可以直接释放内存,所以先释放数组,在释放队列

void QueueFree(CircularQueue* obj) {free(obj->a);//释放数组free(obj);//释放队列
}

4、代码汇总

#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
typedef int QDataType;
//结构定义
typedef struct CircularQueue{QDataType* a;//存放数据数组int front;//头结点int back;//尾结点后一个,有效数据个数int k;//元素个数
} CircularQueue;
//初始化
CircularQueue* InitQueue(int k)
{CircularQueue* obj=(CircularQueue*)malloc(sizeof(CircularQueue));//为队列分配空间obj->a=(int*)malloc(sizeof(int)*(k+1));obj->front=obj->back=0;//初始队列为空,头尾指针都指向0的位置obj->k=k;return obj;
}
//判断是否为空
bool QueueEmpty(CircularQueue* obj) {return obj->front==obj->back;//头尾结点相等时则为空
}
//判断是否为满
bool QueueFull(CircularQueue* obj) {return (obj->back+1)%(obj->k+1)==obj->front;//尾结点的下一个等于头结点则为满
}
//入队
bool EnQueue(CircularQueue* obj, int value) {//满了返回falseif(QueueFull(obj)){return false;}obj->a[obj->back]=value;//插入有效数据obj->back++;obj->back%=(obj->k+1);//进入循环,不能超过最大个数return true;
}
//出队
bool DeQueue(CircularQueue* obj) {//如果为空返回falseif(QueueEmpty(obj)){return false;}obj->front++;//出队则头结点往前走obj->front%=(obj->k+1);return true;
}
//获取队头元素
int QueueFront(CircularQueue* obj) {//为空返回-1if(QueueEmpty(obj))return -1;return obj->a[obj->front];
}
//获取队尾元素
int QueueRear(CircularQueue* obj) {//为空返回-1if(QueueEmpty(obj))return -1;//有一种特殊情况 不是back-1//1.//return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];return obj->a[(obj->back+obj->k)%(obj->k+1)];//2.// if(obj->back==0)// {//     return obj->a[obj->k];// }// else// {//     return obj->a[obj->back-1];// }
}
//销毁
void QueueFree(CircularQueue* obj) {free(obj->a);free(obj);
}

循环队列OJ链接
循环队列

总结

本篇博客就结束啦,谢谢大家的观看,如果公主少年们有好的建议可以留言喔,谢谢大家啦!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/603375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经典八股文之RocketMQ

核心概念 NameServer nameserver是整个rocketmq的大脑&#xff0c;是rocketmq的注册中心。broker在启动时向所有nameserver注册。生产者在发送消息之前先从 NameServer 获取 Broker 服务器地址列表(消费者一 样)&#xff0c;然后根据负载均衡算法从列表中选择一台服务器进行消…

用通俗易懂的方式讲解:万字长文带你入门大模型

告别2023&#xff0c;迎接2024。大模型技术已成为业界关注焦点&#xff0c;你是否也渴望掌握这一领域却又不知从何学起&#xff1f; 本篇文章将特别针对入门新手&#xff0c;以浅显易懂的方式梳理大模型的发展历程、核心网络结构以及数据微调等关键技术。 如果你在阅读中收获…

优化IP地址管理:实现高效、智能的IP资源监控与分配

在当今高度信息化的时代&#xff0c;IP地址管理已成为企业网络运营的核心环节。为了更好地应对不断增长的网络设备和应用需求&#xff0c;提高企业运营效率&#xff0c;监控易推出的IP地址管理工具&#xff0c;将助力企业实现更高效、更智能的IP地址监控与分配。 一、IP地址概…

Jupyter Lab 入门指南:基础篇

&#x1f31f;&#x1f30c; 欢迎来到知识与创意的殿堂 — 远见阁小民的世界&#xff01;&#x1f680; &#x1f31f;&#x1f9ed; 在这里&#xff0c;我们一起探索技术的奥秘&#xff0c;一起在知识的海洋中遨游。 &#x1f31f;&#x1f9ed; 在这里&#xff0c;每个错误都…

MySQL中的开发基于Python的SQL工具类操作数据库简单示例

操作数据库封装SQL工具类的两种方式 为了更方便的实现基于连接池和pymysql 连接数据库&#xff0c;需开发一个sql工具类来让sql操作更简洁用两张方式来封装SQL工具类 1 &#xff09;单例模式 封装 db.py 工具类 import pymysql from dbutils.pooled_db import PooledDBclas…

【uniapp】APP打包上架应用商-注意事项

初雪云-uniapp启动图自定义生成&#xff08;支持一键生成storyboard&#xff09; 一、修改App端上传图片/视频 uni.uploadFile let thatthis; uni.chooseImage({count: 1,sourceType: [camera,album],sizeType: [compressed, original],success: rey > {uni.showLoading({ t…

通过分析 JDK 源代码研究 Hash 存储机制

HashMap 和 HashSet 是 Java Collection Framework 的两个重要成员&#xff0c;其中 HashMap 是 Map 接口的常用实现类&#xff0c;HashSet 是 Set 接口的常用实现类。虽然 HashMap 和 HashSet 实现的接口规范不同&#xff0c;但它们底层的 Hash 存储机制完全一样&#xff0c;甚…

dp--70.爬楼梯/easy 熟悉度C

70.爬楼梯 1、题目2、题目分析2.1 动态规划的三个特征&#xff1a;2.2 如何定义动态规划的状态 3、解题步骤4、复杂度最优解代码示例5、抽象与扩展 1、题目 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&am…

企业网盘全方位解读:热门云存储工具的优势与适用场景

企业网盘无疑是当下最热门的企业协同工具。什么是企业网盘&#xff1f;企业网盘与个人网盘又有什么不同呢&#xff1f;一文全方位解读企业网盘这一热门云存储工具。 什么是企业网盘 企业网盘为企业级文件存储、管理与共享平台&#xff0c;企业团队可以在企业网盘中存储企业文…

基于eNSP的IPv6校园网络规划与设计_综合实验

作者&#xff1a;BSXY_19计科_陈永跃 BSXY_信息学院 注&#xff1a;未经允许禁止转发任何内容 基于eNSP的IPv6校园网络规划与设计&#xff08;综合实验&#xff09; 前言及技术/资源下载说明&#xff08; **未经允许禁止转发任何内容** &#xff09;一、设计topo图与设计要求二…

新概念英语第二册(21)

【New words and expressions】生词和短语&#xff08;4&#xff09; mad adj. 发疯 reason n. 原因 sum n. 量 determined adj. 坚定的&#xff0c;下决心的 ★mad …

【设计模式】备忘录模式

一起学习设计模式 目录 前言 一、概述 二、结构 三、案例实现 1、 “白箱”备忘录模式 2、“黑箱”备忘录模式 四、优缺点 五、使用场景 总结 前言 【设计模式】备忘录模式——行为型模式。 一、概述 备忘录模式提供了一种状态恢复的实现机制&#xff0c;使得用户可以…

Maven之多环境配置与应用

多环境配置与应用 1. 多环境配置作用 maven提供配置多种环境的设定&#xff0c;帮助开发者使用过程中快速切换环境 2. 多环境配置步骤 2.1 定义多环境 <!--定义多环境--> <profiles><!--定义具体的环境&#xff1a;生产环境--><profile><!--定义…

信息学奥赛一本通-编程启蒙3259:练42.5 大象喝水

3259&#xff1a;练42.5 大象喝水 时间限制: 1000 ms 内存限制: 65536 KB 提交数: 1234 通过数: 682 【题目描述】 一只大象口渴了&#xff0c;要喝 2020 升水才能解渴&#xff0c;但现在只有一个深 hh 厘米&#xff0c;底面半径为 rr 厘米的小圆桶&#xff08;hh…

npm、pnpm和yarn 的区别

包管理工具是JavaScript开发中不可或缺的一部分&#xff0c;它们可以帮助我们方便地安装、更新、删除和管理项目所依赖的各种库和模块。 目前&#xff0c;最流行的包管理工具有npm、yarn和pnpm&#xff0c;它们各有各的特点和优劣势。 本文将试着对这三个工具进行全面的对比。…

Android学习(三):在Android虚拟机中运行项目

Android学习&#xff08;三&#xff09;&#xff1a;在Android虚拟机中运行项目 一、前期准备 在系统环境变量中添加ANDROID_SDK_HOME&#xff0c;把值指定到一个其他目录。就可以把Android AVD(虚拟机)创建在指定目录下。修改环境变量后&#xff0c;如果Android Studio是在运…

ROS-[ERROR] [1704543158.960463911]: length [stent_height] is not a valid float

出现如图所示报错 原因&#xff1a;未能正确调用&#xff0c;忘记加${}了

大数据平台Bug Bash大扫除最佳实践

一、背景 随着越来越多的"新人"在日常工作以及大促备战中担当大任&#xff0c;我们发现仅了解自身系统业务已不能满足日常系统开发运维需求。为此&#xff0c;大数据平台部门组织了一次Bug Bash活动&#xff0c;既能提升自己对兄弟产品的理解和使用&#xff0c;又能…

Nginx: 弱扫和安全策略

Nginx弱扫和安全策略 最近在公司配置Nginx,一下子又变成了运维人员 ╮(╯▽╰)╭ , 这是我整理对 服务器弱扫 的一些 配置 server {#监听443端口listen 443;#你的域名server_name www.example.com; // 域名ssl_certificate www.example.com.crt; // https 证书ss…

使用UDP和JSON在C#中高效发送结构体数据

使用UDP和JSON在C#中高效发送结构体数据 引言 在许多网络编程场景中&#xff0c;我们经常需要在不同的应用程序或服务之间发送和接收数据。UDP&#xff08;用户数据报协议&#xff09;因其低延迟和少开销的特点&#xff0c;在需要快速数据传输的场景中非常有用。本文介绍了如何…