队列的定义

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

定义

记住队列是先进先出,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. SQL HAVING 子句详解:在 GROUP BY 中更灵活的条件筛选

    SQL HAVING子句 HAVING子句被添加到SQL中,因为WHERE关键字不能与聚合函数一起使用. HAVING语法 SELECT column_name(s) FROM table_name ...

  2. 攻防世界 Mine- IDA静调或x64dbg动调 两种方式

    刷攻防世界的最后一道二星题,记录一下,大佬请飘过 题目 分析过程 我很勇,我先双击看看这是什么 是一个扫雷游戏,第一下运气好没踩雷,发现无法继续输入了:如果运气不好,会输出"您踩雷啦!&qu ...

  3. spring复习(一)框架概述和spring中基于xml的IOC配置

    1.spring框架概述和spring中基于xml的IOC配置 简介 Spring是分层的 Java SE/EE应用 full-stack 轻量级开源框架,以 IoC(Inverse Of Contr ...

  4. Linux(CentOS7.2)安装cnpm

    1.安装cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org 2.如下安装成功 /root/node-v10.16.3 ...

  5. leetcode:763. 划分字母区间

    763. 划分字母区间 字符串 S 由小写字母组成.我们要把这个字符串划分为尽可能多的片段,同一个字母只会出现在其中的一个片段.返回一个表示每个字符串片段的长度的列表. 示例 1: 输入: S = & ...

  6. 认识tensorflow - 【老鱼学tensorflow2】

    深度学习是模仿了生物的神经元的概念,你可以想象用一大堆的神经元通过各种刺激来对外部世界进行感知,从而建立起对外部世界的模型. 比如给你一个数据对: x y -1 -3 0 -1 1 1 2 3 3 5 ...

  7. Django框架——Q查询进阶、ORM查询优化、事务操作、字段类型、字段参数、Ajax、Content—Type、ajax携带文件

    Q查询进阶 from django.db.models import Q q_obj = Q() # 1.产生q对象 q_obj.connector = 'or' # 默认多个条件的连接是and可以修 ...

  8. boltdb 介绍

    介绍 BoltDB 是一个用 Go 语言编写的嵌入式键/值数据库.以下是关于 BoltDB 的一些基本介绍: 键/值存储: BoltDB 为应用程序提供了简单的键/值存储接口. 事务: BoltDB ...

  9. PTA前三次题目集总结

    以下内容是我对PTA三次习题作业最后一题的思路,源码以及总结 学到的java知识大多都来自写题目集 这些题目对我对java的认知与学习起到了不小的帮助 答题判题程序-1 题目内容 设计实现答题程序,模 ...

  10. 力扣448(java)-找到数组中所有消失的数(简单)

    题目: 给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内.请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果. 示例 ...