《数据结构学习笔记---第九篇》---循环队列的实现

   文章目录

1.循环队列的定义

2.循环队列的判空判满

3.创建队列并初始化

4.入队和出队

5. 返回队尾队首元素

6.释放循环队列


1.循环队列的定义

定义:存储队列元素的表从逻辑上被视为一个环。

       

我们此次实现的循环队列,采用顺序表

typedef struct {int*a;int front;int rear;int k;} MyCircularQueue;

本质上是一个出入受限的顺序表,那我们是怎么实现他的环状结构的呢?毕竟顺序表是一个线性的结构而不是环状的。

答  他用取模运算刚好在存储空间上变成了“环状”。

例如:我们要走一个环状顺序表

如果我们将rear=1;front=2在逻辑上我们可以正常移动,但其实我们物理存储上的指针已经溢出了,所以我们刚好可以取模来控制指针的移动。

如果我们尾指针前进一步就可以(Q.rear+1)% k,刚好可以到达front的位置。

2.循环队列的判空判满

如图我们可以看到,此时rear==front既可以是判空的条件,也可以是判满的条件,那我们应该怎么区分呢?有三种方法://这里的指针变量会和题目中的不太一样,但是判断逻辑相同

1.牺牲一个单元来进行区分

队满:(Q.rear+1)%MaxSize ==Q.front;

队空:   Q.front==Q.rear

2.设置一个Size表示队列元素长度来判断。

队满:Size==MaxSize;

队空:Size==0

3.设置一个 tag标记

tag==0&& Q.front==Q.rear,队空;

tag==1&& Q.front==Q.rear,队满。

  • isEmpty(): 检查循环队列是否为空。
  • isFull(): 检查循环队列是否已满。

bool myCircularQueueIsEmpty(MyCircularQueue* obj) {assert(obj);if(obj->rear==obj->front ){return  true;}return false ;
}bool myCircularQueueIsFull(MyCircularQueue* obj) {assert(obj);if((obj->rear+1)%(obj->k+1)==obj->front ){return  true;}return false ;
}

3.创建队列并初始化

MyCircularQueue(k): 构造器,设置队列长度为 k 

MyCircularQueue* myCircularQueueCreate(int k)
{MyCircularQueue*obj=(MyCircularQueue*)malloc(sizeof(MyCircularQueue));//创建一个循环的队列结构体指针节点obj->a=(int*)malloc(sizeof(int)*(k+1)) ;//队列长度为k,但是要多一个空间用来判断空还是满obj->front=obj->rear=0;obj->k=k;return obj;
}

    队列长度为k,但是要多一个空间用来判断空还是满 ,所以我们用的是第一种判空判满策略,牺牲一个存储空间

4.入队和出队

入队操作:    obj->a[obj->rear]=value;
                    obj->rear=(obj->rear+1)%(obj->k+1);//  先赋值再移动指针

出队操作:   obj->front=(obj->front+1)%(obj->k+1);// 直接移动指针

  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。
  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。
bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {assert(obj);if (myCircularQueueIsFull(obj)){return false;}obj->a[obj->rear]=value;obj->rear=(obj->rear+1)%(obj->k+1);return true;}bool myCircularQueueDeQueue(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return false;}obj->front=(obj->front+1)%(obj->k+1);return true;
}

5. 返回队尾队首元素

  • Front: 从队首获取元素。如果队列为空,返回 -1 。
  • Rear: 获取队尾元素。如果队列为空,返回 -1 。
int myCircularQueueFront(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}return obj->a[obj->front];}int myCircularQueueRear(MyCircularQueue* obj) {assert(obj);if (myCircularQueueIsEmpty(obj)){return -1;}else{int rear=obj->rear==0 ? obj->k : obj->rear-1;return obj->a[rear];  }
}

int rear=obj->rear==0 ? obj->k : obj->rear-1;  由于队尾后面还有一个用于判空判满的空间,如果rear刚好指向这片空间,他实际上是指向的真正的队尾下标为k;如果不为0说明他指向的空间为正常的前驱结点。

 6.释放循环队列

 切记:  先释放结构体指针指向的创建的队列所在的空间,再去释放结构体指针的空间。

void myCircularQueueFree(MyCircularQueue* obj) {free(obj->a);free(obj);
}

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

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

相关文章

9、逆序对的数量(含源码)

逆序对的数量 难度&#xff1a;简单 题目描述 给定一个长度为n的整数数列&#xff0c;请你计算数列中的逆序对的数量。 逆序对的定义如下&#xff1a;对于数列的第 i 个和第 j 个元素&#xff0c;如果满足 i < j 且 a[i] > a[j]&#xff0c;则其为一个逆序对&#xf…

Open3D(C++) 基于三维激光扫描点云的树冠体积计算方法

目录 一、算法原理1、原理概述2、参考文献二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、原理概述 针对树冠形状不规则,树冠体积难以测量和计算的问题,提出一种基于三…

Html提高——视频标签音频标签及其相关属性

HTML5 在不使用插件的情况下&#xff0c;也可以原生的支持音视频格式文件的播放&#xff0c;当然&#xff0c;支持的格式是有限的。 1、video标签 1.1、video标签的语法 <video src"文件地址" controls"controls"></video> video标签的内部…

7.java openCV4.x 入门-Mat之转换、重塑与计算

专栏简介 &#x1f492;个人主页 &#x1f4f0;专栏目录 点击上方查看更多内容 &#x1f4d6;心灵鸡汤&#x1f4d6;我们唯一拥有的就是今天&#xff0c;唯一能把握的也是今天建议把本文当作笔记来看&#xff0c;据说专栏目录里面有相应视频&#x1f92b; &#x1f9ed;文…

全国土壤类型分布数据/土壤有机质/土壤含水量分布/土壤温度/土壤质地/土壤PH

数据下载链接&#xff1a;数据下载链接 引言 土壤是指地球表面的一层疏松的物质&#xff0c;由各种颗粒状矿物质、有机物质、水分、空气、微生物等组成&#xff0c; 能生长植物。土壤是一个国家最重要的自然资源&#xff0c;它是农业发展的物质基础。我国幅员辽阔&#xff0c;自…

SD-WAN组网面临的安全挑战?如何提供有效的安全措施

SD-WAN&#xff08;软件定义广域网&#xff09;技术的广泛应用&#xff0c;企业面临着越来越多的网络安全挑战。尽管SD-WAN带来了灵活性和效率的提升&#xff0c;但其开放性和基于云的特性也带来了一系列安全威胁。本文将探讨SD-WAN组网面临的安全挑战&#xff0c;并提供一些有…

0201基础集成与使用-微信支付-支付模块-项目实战

文章目录 一、前言二、springboot集成2.1 配置信息与配置类2.2 微信相关枚举信息2.3 工具类2.4 业务接口 三、演示-支付与退款结语 一、前言 下面我以微信支付v3为例&#xff0c;通过spirngboot集成到我们的项目中&#xff0c;不依赖其他第三方框架。当然适用简单项目&#xf…

Linux多进程通信(4)——消息队列从入门到实战!

Linux多进程通信总结——进程间通信看这一篇足够啦&#xff01; 1.基本介绍 1&#xff09;消息队列的本质其实是一个内核提供的链表&#xff0c;内核基于这个链表&#xff0c;实现了一个数据结构&#xff0c;向消息队列中写数据&#xff0c;实际上是向这个数据结构中插入一个…

Vue项目登录页实现获取短信验证码的功能

之前我们写过不需要调后端接口就获取验证码的方法,具体看《无需后端接口,用原生js轻松实现验证码》这个文章。现在我们管理后台有个需求,就是登录页面需要获取验证码,用户可以输入验证码后进行登录。效果如下,当我点击获取验证码后能获取短信验证码: 这里在用户点击获取…

win11安装WSL UbuntuTLS

win11安装WSL WSL 简介WSL 1 VS WSL 2先决要求安装方法一键安装通过「控制面板」安装 WSL 基本命令Linux发行版安装Ubuntu初始化相关设置root用户密码网络工具安装安装1panel面板指导 WSl可视化工具问题总结WSL更新命令错误Ubuntu 启动初始化错误未解决问题 WSL 简介 Windows …

Sybase ASE中的char(N)的坑以及与PostgreSQL的对比

1背景 昨天,一朋友向我咨询Sybase ASE中定长字符串类型的行为,说他们的客户反映,同样的char类型的数据,通过jdbc来查,Sybase库不会带空格,而PostgreSQL会带。是不是这样的?他是PostgreSQL的专业大拿,但因为他手头没有现成的Sybase ASE环境,刚好我手上有,便于一试。 …

hive 慢sql 查询

hive 慢sql 查询 查找 hive 执行日志存储路径&#xff08;一般是 hive-audit.log &#xff09; 比如&#xff1a;/var/log/Bigdata/audit/hive/hiveserver/hive-audit.log 解析日志 获取 执行时间 执行 OperationId 执行人 UserNameroot 执行sql 数据分隔符为 \001 并写入 hiv…

vuepress-theme-hope 添加谷歌统计代码

最近做了个网站,从 cloudflare 来看访问量,过去 30 天访问量竟然有 1.32k 给我整懵逼了,我寻思不应该呀,毕竟这个网站内容还在慢慢补充中,也没告诉别人,怎么就这么多访问?搜索了下, cloudflare 还会把爬虫的请求也就算进来,所以数据相对来说就不是很准确 想到了把 Google An…

如何同时安全高效管理多个谷歌账号?

您的业务活动需要多个 Gmail 帐户吗&#xff1f;出海畅游&#xff0c;Gmail账号是少不了的工具之一&#xff0c;可以关联到Twitter、Facebook、Youtube、Chatgpt等等平台&#xff0c;可以说是海外网络的“万能锁”。但是大家都知道&#xff0c;以上这些平台注册多账号如果产生关…

Cisco交换机安全配置

Cisco交换机安全配置 前提 我们以下命令一般都要先进入Config模式 S1> enable S1# conf t S1(config)#端口安全保护 禁用未使用的端口 以关闭fa0/1到fa0/24的端口为例 S1(config)# interface range fa0/1-24 S1(config-if-range)# shutdown缓解MAC地址表攻击 防止CAM…

蓝桥杯刷题第六天(昨天忘记发了)

今天想从不一样的角度来解题&#xff1a;从时间紧张暴力求解到思路阔达直接通过所有案例 暴力方法&#xff1a; 思路第一眼看到这个问题我就想到了第一个思路就是先用两个数组一个存石子数一个存颜色状态&#xff0c;每次遍历一遍看看有没有相邻石子颜色一样且为和最小的。 im…

前端订阅后端推送WebSocket定时任务

0.需求 后端定时向前端看板推送数据&#xff0c;每10秒或者30秒推送一次。 1.前言知识 HTTP协议是一个应用层协议&#xff0c;它的特点是无状态、无连接和单向的。在HTTP协议中&#xff0c;客户端发起请求&#xff0c;服务器则对请求进行响应。这种请求-响应的模式意味着服务器…

Spring-IoC 基于注解

基于xml方法见&#xff1a;http://t.csdnimg.cn/dir8j 注解是代码中的一种特殊标记&#xff0c;可以在编译、类加载和运行时被读取&#xff0c;执行相应的处理&#xff0c;简化 Spring的 XML配置。 格式&#xff1a;注解(属性1"属性值1",...) 可以加在类上…

纯C代码模板

一、快排 void QuickSort(int *a,int left,int right){if(left>right) return;else{int low left,high right;int pivot a[low];while(low<high){while(a[high] > pivot && low < high){high--;}a[low] a[high]; //必须先动a[low]while(a[low] < …

工厂方法模式与抽象工厂模式的深度对比

​&#x1f308; 个人主页&#xff1a;danci_ &#x1f525; 系列专栏&#xff1a;《设计模式》 &#x1f4aa;&#x1f3fb; 制定明确可量化的目标&#xff0c;坚持默默的做事。 &#x1f680; 转载自&#xff1a;设计模式深度解析&#xff1a;工厂方法模式与抽象工厂模式的深…