环形队列

在网上看到一篇比较好的介绍队列的文章,地址为:http://www.cnblogs.com/kubixuesheng/p/4104802.html

特此感谢原创作者,以下均为摘抄。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1、顺序队列

 限制仅在表头删除和表尾插入的顺序表,利用一组地址连续的存储单元依次存放队列中的数据元素。因为队头和队尾的位置是变化的,所以也要设头、尾指针。  

 

初始化时的头尾指针,初始值均应置为 0。 入队尾指针增 1 ,出队头指针增 1 。头尾指针相等时队列为空,在非空队列里,头指针始终指向队头元素,尾指针始终指向队尾元素的下一位置。

初始为空队列,那么头尾指针相等。

入队,那么尾指针加1,头指针不变。先进先出,J1先进队,则 rear+1,尾指针始终指向队尾元素的下一位!如,J2进队,rear 继续+1,J3进队,尾指针继续加1,如图

 

出队,则尾指针不变,头指针加1,注意这里都是加1,先进先出原则,J1先删除,front+1,指向了 J2,J2删除,front+1指向了 J3,如图

 

最后,J3删除,则头指针再次和尾指针相等,说明队列空了。如图

在顺序队列中,当尾指针已经指向了队列的最后一个位置的下一位置时,若再有元素入队,就会发生“溢出”。如图位置,再次入队,就会溢出。

 

2、循环队列的诞生

顺序队列的 “假溢出” 问题:队列的存储空间未满,却发生了溢出。很好理解,比如 rear 现在虽然指向了最后一个位置的下一位置,但是之前队头也删除了一些元素,那么队头指针经历若干次的 +1 之后,遗留下了很多空位置,但是顺序队列还在傻乎乎的以为再有元素入队,就溢出呢!肯定不合理。故循环队列诞生!

解决“假溢出”的问题有两种可行的方法:

(1)、平移元素:把元素平移到队列的首部。效率低。否决了。

(2)、将新元素插入到第一个位置上,构成循环队列,入队和出队仍按“先进先出”的原则进行。操作效率高、空间利用率高。

      

虽然使用循环队列,解决了假溢出问题,但是又有新问题发生——判空的问题,因为仅凭 front = rear 不能判定循环队列是空还是满。比如如图:

这是空循环队列的样子

这是满循环队列的样子

解决办法:

(1)、另设一个布尔变量以区别队列的空和满;

(2)、少用一个元素的空间,约定入队前测试尾指针在循环下加 1 后是否等于头指针,若相等则认为队满;(最常用)

(3)、使用一个计数器记录队列中元素的总数。

对于第2个方案,必须牺牲一个元素的空间,那么入队的时候需要测试,循环意义下的加 1 操作可以描述为:

1     if (rear + 1 = MAXQSIZE)
2 
3            rear = 0;
4 
5      else
6 
7           rear ++; 

 

利用模运算可简化为:

 

1 rear = (rear + 1)% MAXQSIZE  

基本操作

复制代码
 1 #ifndef ___queue_Header_h2 #define ___queue_Header_h3 #include <stdio.h>4 #include <stdlib.h>5 #define MAX_SIZE 56 7 typedef struct{8     int *base;9     int rear;//如果队列不空,指向队尾元素的下一个位置
10     int front;//初始的时候指向表头
11 } CirularQueue;
12 
13 //初始化
14 void initQueue(CirularQueue *queue)
15 {
16     queue->base = (int *)malloc(MAX_SIZE*sizeof(int));
17     
18     if (NULL == queue->base) {
19         exit(0);
20     }
21     
22     queue->front = queue->rear = 0;
23 }
复制代码

求长度

复制代码
//求长度
int getLength(CirularQueue queue)
{//这样把所以的情况都考虑到了return (queue.rear - queue.front + MAX_SIZE) % MAX_SIZE;
}
复制代码

第一种情况,长度的求法

第二种情况,长度的求法,利用模运算,两个情况合二为一!

复制代码
//入队,先判满
void insertQueue(CirularQueue *queue, int e)
{if ((queue->rear + 1) % MAX_SIZE == queue->front) {puts("循环队列是满的!");}else{queue->base[queue->rear] = e;queue->rear = (queue->rear + 1) % MAX_SIZE;}
}
复制代码

如下时为满,损失一个空间,不存储元素。方便判满

1 //出队2 void deleteQueue(CirularQueue *queue)3 {4     if (queue->front == queue->rear) {5         puts("队列是空的!");6     }7     else8     {9         queue->front = (queue->front + 1) % MAX_SIZE;
10     }
11 }
12 
13 //遍历
14 void traversal(CirularQueue queue)
15 {
16     int q = queue.front;
17     
18     for (int i = 0; i < getLength(queue); i++) {
19         printf("循环队列的第%d个元素为%d\n", i + 1, queue.base[q]);
20         q ++; 
21 }
22 }
23
24 #endif

为了尊重原创我将原作者的代码贴上来了,但对最后一个遍历持保留意见,我觉得后面直接q++不会有问题吗?

我个人觉得应该改成:

//遍历
void traversal(CirularQueue queue)
{int q = queue.front;for (int i = 0; i < getLength(queue); i++) {printf("循环队列的第%d个元素为%d\n", i + 1, queue.base[q]);q = (q + 1)%MAX_SIZE; } 
}  

  

 

转载于:https://www.cnblogs.com/kent-hu/p/7580960.html

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

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

相关文章

HTTP1.0、HTTP1.1 、SPDY、HTTP2.0之演变过程和优化

一、协议的演变过程和时间 HTTP1.0(1996年) -> HTTP1.1(1999年) -> SPDY(2012年google提出了SPDY的方案) -> HTTP2.0(2013年8月进行首次合作共事性测试) 二、影响一个HTTP网络请求的因素 主要有两个:带宽和延迟 1)带宽:网络基础建设已经使得带宽得到极大的提升…

OK335xS GPMC nand device register hacking

/********************************************************************************** OK335xS GPMC nand device register hacking* 说明&#xff1a;* 由于最近遇到No NAND device found这个内核错误&#xff0c;在网络上也没找到很好的* 解决办法&am…

Blazor University (19)使用 RenderFragments 模板化组件 —— 数据传递

原文链接&#xff1a;https://blazor-university.com/templating-components-with-renderfragements/passing-data-to-a-renderfragement/将数据传递给 RenderFragment源代码[1]到目前为止&#xff0c;我们使用了仅包含子标记的 RenderFragments&#xff0c;然后在渲染组件时按…

一头扎进Node(三) - File System

file.open:异步模式打开文件 fs.open(path, flags[, mode], callback) 案例代码如下&#xff1a; var fs require(fs);/*** 参数说明&#xff1a;* 1.path&#xff1a;要打开的文件的文件路径* 2.flags&#xff1a;打开文件的方式 读/写* r&#xff1a;只读方式打开文件…

《零基础看得懂的C语言入门教程 》——(十二)原来结构体是这么回事

一、学习目标 了解C语言的结构体的使用方法了解C语言结构体的结构的赋值了解多种C语言结构体变量的赋值方法和取值方法 目录 C语言真的很难吗&#xff1f;那是你没看这张图&#xff0c;化整为零轻松学习C语言。 第一篇&#xff1a;&#xff08;一&#xff09;脱离学习误区 第…

【学生选课系统经典】C#与SQLSERVER连接:Windows应用工程案例

实验任务描述 1 用C#访问SQLSERVER数据库(两种安全模式); 2 用C#完成数据库指定表上的数据显示; 3 用C#完成数据库指定表上的数据插入、删除和更新; 4 用C#完成数据库用户验证。 注意,由于C#语言的强大功能,下面的代码适用于SQLSERVER2000、也适合于SQLSERVER2005。区别仅…

Java精选笔记_JDBC

JDBC概述 什么是JDBC JDBC全称是Java数据库连接&#xff08;Java Database Connectivity&#xff09;&#xff0c;应用程序可通过这套API连接到关系数据库&#xff0c;并使用SQL语句来完成对数据库中数据的查询、更新和删除等操作。是一套用于执行SQL语句的Java API。Java的数据…

mysql关系数据库引擎_MySQL数据库引擎详解

作为Java程序员&#xff0c;MySQL数据库大家平时应该都没少使用吧&#xff0c;对MySQL数据库的引擎应该也有所了解&#xff0c;这篇文章就让我详细的说说MySQL数据库的Innodb和MyIASM两种引擎以及其索引结构。也来巩固一下自己对这块知识的掌握。Innodb引擎Innodb引擎提供了对数…

Java之synchronized的JVM底层实现原理精简理解

1 synchronized的JVM底层原理实现的精简理解 Java 虚拟机中的synchronized基于进入和退出Monitor对象&#xff08;也称为管程或监视器锁&#xff09;实现&#xff0c; 无论是显式同步(synchronized作用在同步代码块&#xff0c;有明确的 monitorenter 和 monitorexit 指令) 还是…

三分钟掌握Actor和CSP模型

点击上方蓝字进行关注前文传送门&#xff1a;《三分钟掌握共享内存模型和 Actor模型》&#xff0c; 一直想比较Actor模型与golang的CSP模型&#xff0c;经过一段时间的实战记录了本文。Actor vs CSP模型• 传统多线程的的共享内存&#xff08;ShareMemory&#xff09;模型使用l…

DateTimeToUnix/UnixToDateTime 对接时间转换

问题&#xff0c;通过毫秒数来解析出时间&#xff1a;&#xff08;很多对接的时候经常需要用到&#xff09; <?php $MyJson {"jingdong_vas_subscribe_get_responce":{"code":"0","item_code":"FW_GOODS-2236-1","…

【学生选课系统经典】VB与SQLSERVER连接:Windows应用工程案例

实验任务描述 1 用VB6访问SQLSERVER数据库(两种安全模式); 2 用VB6完成数据库指定表上的数据显示; 3 用VB6完成数据库指定表上的数据插入、删除和更新; 4 用VB6完成SQLSERVER2008数据库用户验证。 一、数据库系统 该实验中,所要求的数据库名称为SCHOOL,总共涉及以下表:

丢失api-ms-win-crt-runtime-l1-1-0.dll

运行Cmder的时候提示&#xff1a;丢失api-ms-win-crt-runtime-l1-1-0.dll在网上找了一些方法&#xff0c;基本解决方法都是装VC2015的运行时&#xff0c;但是我安装的时候出错&#xff0c;大家可以先试试。接着我就去解决安装出错这问题没&#xff0c;折腾了半天也没成功。后来…

《假如编程是魔法之零基础看得懂的Python入门教程 》——(二)魔法实习生第一步了解魔杖的使用

学习目标 了解什么是开发环境了解python语言的环境安装了解python语言编程的编辑器工具 目录 第一篇&#xff1a;《假如编程是魔法之零基础看得懂的Python入门教程 》——&#xff08;一&#xff09;既然你选择了这系列教程那么我就要让你听得懂 第三篇&#xff1a;《假如编…

Java之synchronized可重入性的理解

1 synchronized可重入性的理解 当一个线程试图操作一个由其他线程持有的对象锁的临界资源时&#xff0c;将会处于阻塞状态&#xff0c;但当一个线程再次请求自己持有对象锁的临界资源时&#xff0c;如果当前锁是重入性&#xff0c;会请求将会成功&#xff0c;如果当前锁不是可…

onmouseover-onmouseout

<input type"checkbox" value"autoLogin" οnmοuseοver"block()" οnmοuseοut"none()">两周内自动登录 <div id"div1">为了您的信息安全请不要在网吧或公共电脑勾选此项</div> <script> functi…

mysql5.7 only_full_group_by_Mysql5.7及以上版本 ONLY_FULL_GROUP_BY报错的解决方法

近期在开发过程中&#xff0c;因为项目开发环境连接的mysql数据库是阿里云的数据库&#xff0c;而阿里云的数据库版本是5.6的。而测试环境的mysql是自己安装的5.7。因此在开发过程中有小伙伴不注意写了有关group by的sql语句。在开发环境中运行是正常的&#xff0c;而到了测试环…

一款高速的NET版的离线免费OCR

PaddleOCR.Onnx一款基于Paddle的OCR&#xff0c;项目使用ONNX模型&#xff0c;速度更快。本项目同时支持X64和X86的CPU上使用。本项目是一个基于PaddleOCR的C代码修改并封装的.NET的工具类库。包含文本识别、文本检测、基于文本检测结果的统计分析的表格识别功能&#xff0c;同…

spring 注解简单使用

一、通用注解 1、项目结构&#xff1a; 2、新建Person类&#xff0c;注解Component未指明id&#xff0c;则后期使用spring获取实例对象时使用默认id"person"方式获取或使用类方式获取 package hjp.spring.annotation.commen;import org.springframework.stereotype.C…

selenium+python笔记3

#!/usr/bin/env python # -*- coding: utf-8 -*- """ desc:学习unittest的用法 注意setUp/setUpClass&#xff0c;tearDown/tearDownClass的区别 ① setUp():每个测试函数运行前运行 ② tearDown():每个测试函数运行完后执行 ③ setUpClass():必须使用classmeth…