环形队列初步探讨

article/2025/9/28 1:43:10

文章目录

  • 前言
  • 一、环形队列
  • 二、环形队列基本操作
  • 二、示例
  • 总结


前言

最近使用队列的时候,在实现大数据整体平移的时候还是用了内存copy虽然暂时达到性能要求,但是总感觉很笨重,最后用环形队列重构了部分代码,效果还行。


一、环形队列

循环队列是一种线性数据结构,其中的操作是基于FIFO(先进先出)原理执行的,最后一个位置又连接回第一个位置以构成一个闭合的环形队列。 也称为“环形缓冲区”。
在普通队列中,我们可以插入元素,直到队列变满。 但是,一旦队列已满,再无法插入下一个元素。因为在环形队列里面有两个索引计数器,每次插入队列rear会+1,每次出队操作,front索引会递增+1
应用场合:此环形队列的最佳实现形式就是固定长度的数组。

因为我们用数组来表示环形队列,数组第一个地址可以认为为头,正因为如此,实现环形结构,在rear位置就要判断是否已经满载了,从而将rear置为0操作。

二、环形队列基本操作

以一个大小为10的数组为例子
在这里插入图片描述
**空环(空载)😗*当front和rear计算器指向同一个元素级别的内存块,定义为空载,(但是不能让front=rear作为判断空载的条件)因此我们使其front或rear重置为一个负数,例如-1就是表示空环状态。
满环(满载):当rear计数器随着在入队操作递增逼近front计数器,此时rear=size-1并且front=0(对应一直入环,此时头指针没有偏移),或者rear=front-1(有入队和出对操作,此时头和尾已经偏离之前0的位置)。
入队:需要判断当前队列信息(尾开始++):
1、满载时候,直接退出;
2、空载,则需要将d_rear = d_front = 0;
3、rear == 9到队列最尾部 并且front 不在0处(不为满载的情况),此时rear =0;
4、除上述情况 rear++;
出队:需要判断当前队列信息(头开始++):
1、空载,直接返回一个空元素;
2、取出当前数据
2.1 rear = front 时候 rear = front=-1 (也就是刚插入一个元素就取出来)
2.2、front = 9(队列尾部时候)front =0;
2.3、除上述情况正常 front++;

二、示例

给出一个循环队列模板类

template <class T>
class CircleQueue
{
private:long mrear, mfront;                       //内部元素队列指针size_t msize;                             //可用大小size_t mmaxsize;                          //最大队列大小T *marr;
public:CircleQueue();                              //默认构造函数CircleQueue(size_t);                        //自定义构造函数~CircleQueue();                             //析构函数CircleQueue(const CircleQueue &);           //拷贝构造函数CircleQueue(CircleQueue &&);                //移动构造函数T deque();                                  //出队列void enque(const T &);                      //入队操作size_t size() const;                        //获取队列大小T front() const;                            //获取端首元素T rear() const;                             //获取末尾元素bool iEmpty() const;                        //队列是否非空bool isFull() const;                        //队列是否已满const size_t size();                        //返回队列已有数量const T *buffer();                          //对列头地址};
#endif

实现

#include "CircleQueue.h"
#define DEFAULT_SIZE 10template <class T>
CircleQueue<T>::CircleQueue()
{mfront = mrear = -1;mmaxsize = DEFAULT_SIZE;msize = 0;marr = new T[mmaxsize];
}//构造函数
template <class T>
CircleQueue<T>::CircleQueue(size_t size)
{msize = 0;mmaxsize = size;mfront = mrear = -1;marr = new T[mmaxsize];
}//析构函数
template <class T>
CircleQueue<T>::~CircleQueue()
{delete[] marr;
}//检查环形队列是否为满载
template <class T>
bool CircleQueue<T>::isFull() const
{return (mrear == mmaxsize - 1 && mfront == 0) || (mrear == mfront - 1);
}//判断环形队列是否为空
template <class T>
bool CircleQueue<T>::isEmpty() const
{return mfront == -1 || mrear == -1;
}//入队操作
template <class T>
void CircleQueue<T>::enque(const T &value)
{if (is_full()){std::cout << "环形队列已满" << std::endl;return;}else if (mfront == -1){mrear = mfront = 0;}else if (mrear == mmaxsize - 1 && mfront != 0){mrear = 0;}else{mrear++;}marr[mrear] = value;msize++;
}//出队操作
template <class T>
T CircleQueue<T>::deque()
{if (is_empty()){std::cout << "环形队列为空!!" << std::endl;return T();}T data = marr[mfront];if (mfront == mrear){mfront = -1;mrear = -1;}else if (mfront == msize - 1){mfront = 0;}else{mfront++;}msize--;return data;
}//获取队头部元素
template <class T>
T CircleQueue<T>::front() const
{return marr[mfront];
}//获取队尾元素
template <class T>
T CircleQueue<T>::rear() const
{return marr[mrear];
}//获取队列尺寸
template <class T>
const size_t CircleQueue<T>::size()
{return msize;
}//获取队列内部的缓存指针
template <class T>
const T *CircleQueue<T>::buffer()
{return marr;
}

总结

环形队列在很多场合都可以应用,搜素效率很高。


http://chatgpt.dhexx.cn/article/LghVBPOZ.shtml

相关文章

环形队列

介绍 环形队列是队列的一种特殊情况&#xff0c;也是基于队列的实现&#xff0c;队列是动态的集合&#xff0c;而环形队列则是固定长度的&#xff0c;当队列满时&#xff0c;则从队首删除元素。其原理基本和队列一致&#xff0c;都是实现先进先出的策略。 实现 先定义数据&…

C语言,环形队列

什么是环形队列&#xff1f; 环形缓冲区是一个非常典型的数据结构&#xff0c;这种数据结构符合生产者&#xff0c;消费者模型&#xff0c;可以理解它是一个水坑&#xff0c;生产者不断的往里面灌水&#xff0c;消费者就不断的从里面取出水。 那就可能会有人问&#xff0c;既然…

数据结构(10)---队列之环形队列

环形队列 文章目录 环形队列什么是环形队列循环队列的实现第一种实现第二种实现 什么是环形队列 环形队列也是队列的一种数据结构, 也是在队头出队, 队尾入队; 只是环形队列的大小是确定的, 不能进行一个长度的增加, 当你把一个环形队列创建好之后, 它能存放的元素个数是确定的…

数据结构--环形队列的介绍与实现

数据结构--环形队列实现 一、环形队列实现原理环形队列的几个判断条件 二、代码实现1.环形队列类&#xff08;CircleQueue&#xff09;2.环形队列类测试类3.程序运行结果4.完整代码 环形队列可以用数组实现&#xff0c;也可以使用循环链表实现.在使用数组实现循环队列的时候&am…

【数据结构(C语言描述)】环形队列

目录 一、基础知识二、数组实现环队2.1 初始化2.2 判断环队是否为空2.3 判断环队是否为满2.4 入队2.5 出队2.6 取队头元素2.7 取队尾元素2.8 销毁环队 三、链表实现环队3.1 初始化3.2 判断环队是否为空3.3 判断环队是否为满3.4 入队3.5 出队3.6 取队头元素3.7 取队尾元素3.8 销…

环形队列原理,全网最通俗易懂

队列是什么 队列是一种很常见的数据结构&#xff0c;满足先进先出的方式&#xff0c;如果我们设定队列的最大长度&#xff0c;那就意味着进队列和出队列的元素的数量实则满足一种动态平衡。 如果我们把首次添加入队列的元素作为一个一维坐标的原点&#xff0c;那么随着队列中…

Mysql 死锁和死锁的解决方案

最近在研究Mysql底层原理&#xff0c;研究到了死锁&#xff0c;感觉挺有意思&#xff0c;在这里和大家分享一下 前置知识&#xff1a;需要了解锁的种类&#xff0c;如表锁、行锁&#xff1b;行锁又分为记录锁、间隙锁、临键锁等等&#xff1b;什么情况下会加表锁&#xff0c;什…

mysql死锁演示

背景&#xff1a; 线上日志突然爆了有数据库死锁的日志。 通过以下语句查询数据库死锁的日志 SHOW ENGINE INNODB STATUS 通过 日志分析&#xff0c;看到了两条update语句并且是里面有子查询。还有两个表的更新顺序问题。 解决方案是&#xff1a;加了分布式锁&#xff0c;…

记录一次mysql死锁

一&#xff0c;死锁发现 项目中有一个接口包含更新操作1&#xff0c;后面发现更新失败&#xff0c;通过查看应用程序日志&#xff0c;发现发生了死锁 sql 1 如下 1.最初版本根据id为条件&#xff0c;更新&#xff08;plan_start_time 二级索引&#xff09; update tt_task …

深入MySQL死锁场景

总结死锁需满足以下条件&#xff1a; 2个或者2个以上的并发事务操作并发事务之间存在锁冲突锁冲突关系成环形 GAP锁和Insert的隐式锁&#xff0c;最容易导致死锁&#xff0c;以下分析从这俩典型场景开始。 1. 表结构 建立以下表作为场景验证&#xff0c;id为主键&#xff0…

mysql死锁查询语句

mysql 死锁:如何解决mysql死锁 可直接在mysql命令行执行&#xff1a;showengineinnodbstatus\G;查看造成死锁的sql语句&#xff0c;分析索引情况&#xff0c;然后优化sql然后showprocesslist;另外可以打开慢查询日志&#xff0c;linux下打开需在my.cnf的[mysqld]里面加上以下内…

MySQL死锁排查步骤

系列文章目录 第一章&#xff1a;sql_mode模式 第二章&#xff1a;optimize table、analyze table、alter table、gh-ost 第三章&#xff1a;InnoDB MVCC原理 第四章&#xff1a;sql语句执行过程 第五章&#xff1a;Percona Toolkit工具简介 第六章&#xff1a;MySQL索引 第七…

MySql死锁过程

死锁一般怎么导致呢&#xff0c; 抛开一堆概念&#xff0c; 我就把死锁当成死结。 就是你代码获取锁的顺序问题。 MySql的死锁和我们正常代码也一样&#xff0c; 都是互通的&#xff0c; 当你修改一个表的行数据的时候&#xff0c; 就需要对那一行数据进行加锁。 所以很容易想…

中秋遇到mysql死锁怎么办

文章目录 前言一、什么是死锁二、死锁的产生条件三、死锁示例四、死锁的分析和查看1.查看最近1个死锁信息2.查看正在运行中的事务信息3.查看加锁信息 五、死锁的内部处理方案1.死锁探测机制2.锁等待超时机制 六、手动释放锁1.表级锁手动释放2.行级锁手动释放 七、死锁的优化策略…

mysql 死锁分析

一、 什么是死锁 死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程.二、 死锁产生的四个必要条件 1.互斥条件&#xff1a;指进…

MySQL死锁分析

背景知识 MySQL数据库InnoDB引擎的行级锁在使用时是在索引记录上加锁的。 行级锁从占有模式上分为&#xff1a; 排他锁&#xff1a;独占行数据&#xff0c;如某事务获取了该行记录的排他锁&#xff0c;其他事务在获取该记录的排他锁和共享锁时需等待&#xff1b;共享锁&…

故障分析 | MySQL死锁案例分析

作者&#xff1a;杨奇龙 网名“北在南方”&#xff0c;资深 DBA&#xff0c;主要负责数据库架构设计和运维平台开发工作&#xff0c;擅长数据库性能调优、故障诊断。 本文来源&#xff1a;原创投稿 *爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转…

MySQL死锁

参考博客&#xff1a; https://blog.csdn.net/sinat_41653656/article/details/109629094 Mysql 锁类型和加锁分析 MySQL有三种锁的级别&#xff1a;页级、表级、行级。 表级锁&#xff1a;开销小&#xff0c;加锁快&#xff1b;不会出现死锁&#xff1b;锁定粒度大&#xff…

mysql死锁语句_Mysql死锁

笔者最近在生产环境错误日志上看到updating database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Deadlock found when trying to get lock; try restarting transaction 这样的日志 ,网上看了很多文章 发现这篇文章 跟自己的场景非常接近…

【MySQL锁篇】MySQL死锁问题以及解决方案

目录 一、MySQL出现死锁的场景 二、MySQL当中的死锁现象 三、Insert语句怎样加锁的 隐式锁&显示锁 记录之间加有间隙锁 遇到唯一键冲突或者主键冲突的时候加锁 如果主键索引重复&#xff1a; ​​​​​​如果唯一二级索引重复: 四、如何避免MySQL当中的死锁现象 方案…