队列的定义

声明: 本篇博客是实现循环队列。

定义

记住队列是先进先出,FIFO——first in first out,
(和栈的区别也是这个,栈是一头开一头闭,就像一个瓶子,先进的后出)
队列就是两头开,但是当队列用于顺序存贮的时候很容易造成假溢出。

假溢出

假设在队满的,但是尾指针指向的是比队列空间的大小还要大一个位置,所以称之为假溢出,这也是造成空间浪费的一个缺点。

空间浪费的缺点

因为队列是先进先出,所以在队头出队,当队头指针和队尾指针指向的位置一样的时候就表示全部出队成功,但是队头以前指向的空间就无法得以继续利用,就造成了空间浪费。

如何解决

这时候假设我们已经队满了,若想要继续录入信息,大家肯定能想到的是回到头指针的位置继续录入信息。
那么一个叫循环队列的算法解决了这个问题,其实就是用指针让队列形成一个闭环,这样既控制了空间的大小,又防止了出栈时候的空间浪费,因为只要有这两个指针在,按顺序录入的时候总能有一个空间给你录入。

循环队列的缺点

其实与其说是缺点,不如说是程序员不应该选择这个循环队列的算法。缺点就是当队列满队了时候,继续录入信息,我们知道队列的尾部指针会重新指向头部指针,这时候就会造成你前面录入的信息丢失,被新录入的信息覆盖掉。

主要的算法思想(重要)

循环队列可以把他想象成小时候经常看到的幸运转盘,按一个方向旋转,所以进队的时候也是按一个方向进,只是把一个顺序队列用一个算法使之成为看似循环的一个队列。

如何理解循环队列(必看)

这里rear是尾部,front是头部,但是我这个不同的是使用尾进尾出的方式,和其他博客有点不一样,我单纯觉得这样比较好理解。

首先分为三个部分
第一部分: 进队
第二部分: 出队
(在你队满了的时候,若还想继续录入信息,进入下一步)
第三部分: 队头移动+1个位置,在队满的情况下+1会造成假溢出,也就是队头队尾相撞了,那么这时候队尾也进行一个+1的操作,这样就实现了队头队尾一直处于连在一起的形式,也就是形成了循环队列。

考虑的因素
队列还没满的时候想出队的话,也不用担心这个算法会出错,因为你出队的时候也包含在了队头+1移动的操作,第三部的算法肯定能满足这个条件,现在我总是不禁感叹前辈们的智慧,太妙了。

***如果看到这也不懂的话,恕我无力回天。 ***

结构体代码

/*单词顺序表*/
typedef struct _Elem{
char *word;//存放单词
int lenth;
int front;
int rear;
}Elem;
Elem *temp = NULL;

两种实现方法

①循环队列,队头和队尾指针连在一起的形式。

(这个方法理解了,那么等下将第二个方法的时候就比较容易理解。)

首先解释一下下面的代码以便理解:
temp结构体,存字符进word这个字符数组里面,word就是一个循环队列,
我们现在是要实现不浪费一个空间写出一个循环队列。

第一个字符进队前,rear和front在同一个位置,但是这时候不能移动空间,因为如果移动了,第一个位置就没有存到信息,所以要再用一个temp->lenth作为判断条件,这个的意思就是当你还没有录入字符的时候,不能进入if语句把front指针进行移动。

下面开始进队,进队的时候把尾部指针rear进行移动+1,所以这时候rear和front指针位置开始不一样了, 这一点很重要,如果没有这步,会直接导致后面的错误。

接下来就是把lenth进行自加,用来记录录入了多少个字符,但是由于该队列是循环队列,不能超过MAXSIZE空间,所以也要一个 限制的大小条件,

#1#: 这时候如果你继续进队,回到第一步的代码里面,进行第二个字符录入,现在可以知道rear和front的位置不一样,所以即使lenth不等于零也无法进入if语句对front指针向前移动+1,←这个是循环队列实现的算法精髓 。
往后就是一直录入,直到rear = (rear + 1)%MAXSIZE;
#2#: 这个语句运行完成后,变成队满状态了,这时候rear和front 同时% MAXZSIZE ←这也是循环队列实现的算法精髓

不会改变你rear和front的位置关系,所以他们队满的时候他们是相等的,如此来
%MAXSIZE不仅不会造成空间溢出,
rear%MAXSIZE ==front%MAXSIZE && temp->lenth!=0中个条件判断将front向前+1移动的操作 把该队列变成了一个循环队列

下面是伪代码:


if(rear ==front%MAXSIZE && temp->lenth!=0)
front = (front+1)%MAXSIZE; temp->word[rear] = ch;
rear = (rear + 1)%MAXSIZE; if(temp->lenth < MAXSIZE)
{
temp->lenth++;
}
}

②浪费一个空间形成循序队列

这个的思想就是不用像第一种方法一样要用一个lenth条件来判断是否已经录入一个字符了,这个方法就是简单粗暴的形式,浪费一个空间来使之直接形成循环队列。

代码区别:
if的判断语句变成了 rear%MAXSIZE ==(front+1)%MAXSIZE,去掉了lenth这部分的代码

具体实现如下:

if(rear ==(front+1)%MAXSIZE) front = (front+1)%MAXSIZE;
temp->word[rear] = ch;
rear = (rear + 1)%MAXSIZE;

③浪费多个空间

其实你理解了第二个思想的话,很简单就能举一反三,只要把所有的+1修改成+2就代表浪费两个空间,这样也能形成闭环,+3、+4只要按照你的需求来修改就可以,需要注意的是千万不能让你的数组越界,浪费几个空间就要保证你的数组空间足够给你去挥霍,不然程序就很容易越界崩溃掉。

结尾

看完后是不是觉得就几行代码就实现了这么强大的循环队列功能,其实我也是这么觉得的,但是真正理解起来确实一丢丢的时间。

注:本博客主要用文字叙述的方式帮助理解,希望能帮助到各位。
因为我觉得文字叙述虽然比不上图表理解来得更快,但是文字叙述会比图表更能透彻的理解队列。所以如果希望各位耐心读完。
(如有错误请私信我,如果确实有错,到时候我可以直接修改喔~)

C数据结构:循环队列的顺序存储结构的更多相关文章

  1. C++编程练习(5)----“实现简单的循环队列的顺序存储结构“

    队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出(First In First Out)的线性表,简称FIFO.允许插入的一端称为队尾,允许删除的一端 ...

  2. C语言数据结构-循环队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作

    1.数据结构-循环队列的实现-C语言 #define MAXSIZE 100 //循环队列的存储结构 typedef struct { int* base; //基地址 int _front; //头 ...

  3. Java数据结构——循环队列

    普通顺序队列存在的问题在普通顺序队列中,入队的操作就是先将尾指针rear右移一个单位,然后将元素值赋值给rear单位.出队时,则是头指针front后移一个单位.像这样进行了一定数量的入队和出队操作后, ...

  4. 数据结构-循环队列(Python实现)

    今天我们来到了循环队列这一节,之前的文章中,我介绍过了用python自带的列表来实现队列,这是最简单的实现方法. 但是,我们都知道,在列表中删除第一个元素和删除最后一个元素花费的时间代价是不一样的,删 ...

  5. java数据结构---循环队列

    #java学习经验总结------循环队列的实现(数组) package datastructure;/*数组实现循环队列 队列first in first out*/ public class Ci ...

  6. c数据结构 -- 线性表之 顺序存储结构 于 链式存储结构 (单链表)

    线性表 定义:线性表是具有相同特性的数据元素的一个有限序列 类型: 1:顺序存储结构 定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构 算法: #include <stdio. ...

  7. C/C++ 数据结构循环队列的实现

    #include <iostream> #include <Windows.h> using namespace std; #define MAXSIZE 6 typedef ...

  8. [PHP] 数据结构-线性表的顺序存储结构PHP实现

    1.PHP中的数组实际上是有序映射,可以当成数组,列表,散列表,字典,集合,栈,队列,不是固定的长度2.数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了3.想要函数的一个参数 ...

  9. 数据结构 - 顺序队列的实行(C语言)

    数据结构-顺序队列的实现 1 顺序队列的定义 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式.我们先来看队列的顺序存储结构. 队列的顺序储存结构:用数组存储队列,为了避 ...

  10. 数据结构算法C语言实现(十二)--- 3.4循环队列&队列的顺序表示和实现

    一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 //3_4_part1.h /** ...

随机推荐

  1. OpenHarmony 3.2 Beta多媒体系列——音视频播放gstreamer

      一. 简介 多媒体播放框架主要的实现在PlayerServer服务中,这个服务提供了媒体播放框架所需要的实现环境,继续跟踪代码分析发现,PlayerServer主要通过gstreamer适配层,对 ...

  2. 本周四晚19:00知识赋能第八期第1课丨ArkUI框架整体设计

    OpenAtom OpenHarmony(以下简称"OpenHarmony")开源开发者成长计划项目自 2021 年 10 月 24 日上线以来已经走过了7期,为开发者提供了一个良 ...

  3. springboot整合redis之发送手机验证码

    阿里云服务发送手机短信验证码-----(第二篇) 文章概述:springboot整合redis之发送手机验证码注册登录 注:搭建springboot项目可以参考这篇文章: 前言:短信验证码是通过发送验 ...

  4. 【FAQ】调用应用内支付SDK时报错,如何用tag对问题进行排查和分析

    华为应用内支付服务(In-App Purchases,IAP)为开发者提供便捷的应用内支付体验和简便的接入流程.开发者的应用集成IAP SDK后,调用IAP SDK接口,启动IAP收银台,即可实现应用 ...

  5. Qt调用摄像头一,基础版

    本示例,为纯Qt调用摄像头,功能比较简单,打开摄像头,设置参数,拍照 涉及到的功能有: 获取摄像头列表 获取摄像头分辨率 获取摄像头帧率 获取摄像头支持的视频模式 设置摄像头参数 拍照 此版本的缺点是 ...

  6. Mac OS 中JDK 环境(jdk 1.8.0_831)安装配置、环境变量配置及卸载操作

    前言: 摊牌了,本来就有点喜新厌旧的我,特意把系统和开发环境都拉到比较高,想试验一下兼容性和某些新特性,探索了一下新大陆,也见识了各种光怪陆离的妖魔鬼怪. 因为要着手云平台项目的重构改版和新系统的架构 ...

  7. 【未测试】CentOS 6.5快速部署HTTP WEB服务器和FTP服务器

    CentOS 6.5快速部署HTTP WEB服务器和FTP服务器 [题记]本文使用CentOS 6.5minimal快速搭建HTTP服务器和仅供授权用户登陆的FTP服务器.意在使用授权FTP用户通过登 ...

  8. Django框架——cookie与session简介、django操作cookie与session、django中间件

    cookie与session简介 """ 回忆:HTTP协议四大特性 1.基于请求响应 2.基于TCP.IP作用于应用层之上的协议 3.无状态 不保存客户端的状态 4.无 ...

  9. 高效使用Java构建工具|Maven篇|云效工程师指北

    ​简介:高效使用Java构建工具|Maven篇.众所周知,当前最主流的Java构建工具为Maven/Gradle/Bazel,针对每一个工具,我将分别从日常工作中常见的场景问题切入,例如依赖管理.构建 ...

  10. 云效Codeup代码评审中的代码协同

    简介: 云效 Codeup 汇集了阿里巴巴最新的代码托管.代码协同技术,希望能够造福更多中国和世界的开发者. 大神说:"Show me the code",于是就有了代码评审. & ...