C数据结构:循环队列的顺序存储结构
顺序队列目录
队列的定义
声明: 本篇博客是实现循环队列。
定义
记住队列是先进先出,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数据结构:循环队列的顺序存储结构的更多相关文章
- C++编程练习(5)----“实现简单的循环队列的顺序存储结构“
队列(queue)是只允许在一端进行插入操作,而在另一端进行删除操作的线性表. 队列是一种先进先出(First In First Out)的线性表,简称FIFO.允许插入的一端称为队尾,允许删除的一端 ...
- C语言数据结构-循环队列的实现-初始化、销毁、清空、长度、队列头元素、插入、删除、显示操作
1.数据结构-循环队列的实现-C语言 #define MAXSIZE 100 //循环队列的存储结构 typedef struct { int* base; //基地址 int _front; //头 ...
- Java数据结构——循环队列
普通顺序队列存在的问题在普通顺序队列中,入队的操作就是先将尾指针rear右移一个单位,然后将元素值赋值给rear单位.出队时,则是头指针front后移一个单位.像这样进行了一定数量的入队和出队操作后, ...
- 数据结构-循环队列(Python实现)
今天我们来到了循环队列这一节,之前的文章中,我介绍过了用python自带的列表来实现队列,这是最简单的实现方法. 但是,我们都知道,在列表中删除第一个元素和删除最后一个元素花费的时间代价是不一样的,删 ...
- java数据结构---循环队列
#java学习经验总结------循环队列的实现(数组) package datastructure;/*数组实现循环队列 队列first in first out*/ public class Ci ...
- c数据结构 -- 线性表之 顺序存储结构 于 链式存储结构 (单链表)
线性表 定义:线性表是具有相同特性的数据元素的一个有限序列 类型: 1:顺序存储结构 定义:把逻辑上相邻的数据元素存储在物理上相邻的存储单元中的存储结构 算法: #include <stdio. ...
- C/C++ 数据结构循环队列的实现
#include <iostream> #include <Windows.h> using namespace std; #define MAXSIZE 6 typedef ...
- [PHP] 数据结构-线性表的顺序存储结构PHP实现
1.PHP中的数组实际上是有序映射,可以当成数组,列表,散列表,字典,集合,栈,队列,不是固定的长度2.数组定义中多个单元都使用了同一个键名,则只使用了最后一个,之前的都被覆盖了3.想要函数的一个参数 ...
- 数据结构 - 顺序队列的实行(C语言)
数据结构-顺序队列的实现 1 顺序队列的定义 线性表有顺序存储和链式存储,队列作为一种特殊的线性表,也同样存在这两种存储方式.我们先来看队列的顺序存储结构. 队列的顺序储存结构:用数组存储队列,为了避 ...
- 数据结构算法C语言实现(十二)--- 3.4循环队列&队列的顺序表示和实现
一.简述 空队列的处理方法:1.另设一个标志位以区别队列是空还是满:2.少用一个元素空间,约定以队列头指针在队尾指针下一位置上作为队列呈满的状态的标志. 二.头文件 //3_4_part1.h /** ...
随机推荐
- Jetty的http2模块
启用http2模块,执行如下命令: java -jar $JETTY_HOME/start.jar --add-modules=http2 命令的输出,如下: INFO : http2 initial ...
- OpenHarmony 3.2 Beta Audio——音频渲染
一.简介 Audio是多媒体子系统中的一个重要模块,其涉及的内容比较多,有音频的渲染.音频的采集.音频的策略管理等.本文主要针对音频渲染功能进行详细地分析,并通过源码中提供的例子,对音频渲染进行流程的 ...
- Numpy数组拼接和分裂
将多个数组合并成一个,或将一个数组分裂成多个. 数组拼接 concatenate([a1, a2, ...], axis=0, out=None) #默认沿axis = 0轴拼接,也可设置沿axis ...
- openGauss Cluster Manager RTO Test
一.环境介绍 软件环境 类别 版本 下载链接 备注 OS openEuler 20.03 (LTS) https://repo.openeuler.org/openEuler-20.03-LTS/IS ...
- 一、Unity调用Xcode封装方法(工程引用文件)
1.Xcode新建Static Library 工程 (我起的名字是UnityExtend 可以在接下来的图中看到) 2.打包unity ios工程 unity打包ios 打出Xcode工程 3.打开 ...
- 重新整理数据结构与算法(c#)—— 二叉树排序树[二十二]
前言 什么是二叉堆排序呢? 就是上面这种,一个节点大于左节点,但是小于右节点,再我写的例子中会写出大于等于右节点. 那么如何让一个数组进行变成这种二叉树呢? 其实只要有规律就很简单. 第一个元素(0) ...
- mmdetection训练自己的模型【数据集转变,数据集划分,数据集gt可视化,mmdetection配置文件生成及修改,开始训练,gradio部署】
针对有一点mmdetction基础的,然后想根据自己的数据集,熟练训练自己的模型.需要改成自己配置的地方,我会在代码中做好标记,方便修改. 我们先了解一下mmdetection的基本流程,你想训练一个 ...
- cv2在图像上画不同比例的锚框
''' cv2在图像上画不同比例的锚框 ''' import cv2 import math # 画宽高比1:1的锚框 def display_11_anchor(img,anchor_11_left ...
- Kafka 集群副本数量调整
Kafka 创建时未指定多个副本或者副本数量过少,都可以在后期手动添加,另外如果副本过多也可以减少,当前调整基于 Kafka 的版本是 2.5.1,但是估计 2.1 ~ 2.5 应该都是兼容的. 下面 ...
- 三款免费强大的SSH工具食用指南
食用清单 XShell FinalShell Electerm 食用方案 XShell 先说说老牌ssh工具XShell吧,用过很多年,说实话没啥别的毛病挺好用的.不过,还是有些地方有待加强,比如文件 ...