当前位置: 首页> 健康> 美食 > 广州市白云区疫情_如何制作app图标_西安关键词排名推广_短视频关键词seo优化

广州市白云区疫情_如何制作app图标_西安关键词排名推广_短视频关键词seo优化

时间:2025/7/31 5:02:45来源:https://blog.csdn.net/Excalibur6/article/details/147238581 浏览次数:0次
广州市白云区疫情_如何制作app图标_西安关键词排名推广_短视频关键词seo优化

核心概念 

循环队列(Circular Queue),也称为环形队列,是一种特殊的队列数据结构。它通过将队列的首尾相连,解决了传统队列因出队操作导致的空间浪费问题(即“假溢出”),从而更高效地利用固定大小的内存空间。


 =

  1. 传统队列的问题

    • 普通队列基于数组实现时,一旦队尾指针(tail)到达数组末尾,即使队列头部有空闲位置,也无法再插入新元素,导致空间无法复用。
    • 例如:数组大小为5,队列经过多次入队和出队后,可能出现头部有空位,但尾部已满的情况,无法继续入队。
  2. 循环队列的解决方案

    • 将数组的逻辑首尾相连,形成一个环。
    • 通过模运算​(%)控制队首(head)和队尾(tail)指针的移动,使其在到达数组末尾后能回到起始位置,重复利用空间。

关键特性

  1. 核心指针

    • head:指向队列的第一个元素。
    • tail:指向下一个可插入元素的位置。
  2. 关键操作

    • 入队(Enqueue)​:向队尾插入元素,tail 指针后移。
    • 出队(Dequeue)​:从队首移除元素,head 指针后移。
  3. 空和满的判定

    • 队列空head == tail 且 count == 0
    • 队列满head == tail 且 count == capacity(通过计数器实现,无需浪费空间)。
      (传统方法可能用 (tail + 1) % capacity == head 判断队列满,但会浪费一个位置)

实现原理

1. ​指针移动规则
  • 入队时tail = (tail + 1) % capacity
  • 出队时head = (head + 1) % capacity
2. ​元素数量计算
  • 通过 count 变量直接记录当前元素数量,无需依赖 head 和 tail 的位置关系。
  • 元素数量:count = (tail - head + capacity) % capacity(未使用 count 时)。
3. ​空间复用
  • 当指针移动到数组末尾时,通过模运算回到数组头部,形成一个逻辑上的“环”。

示例分析

假设队列容量为5,初始状态如下:
head = 0tail = 0count = 0,数组为 [ , , , , ]

  1. 入队4个元素​(62, 84, 26, 89):

    • head=0tail=4count=4,队列为 [62,84,26,89, ]
    • 打印结果:62<-84<-26<-89
  2. 继续入队45

    • vec[4] = 45tail = 0count=5,队列已满。
    • 队列为 [62,84,26,89,45],打印结果:62<-84<-26<-89<-45
  3. 尝试入队46

    • 队列已满,操作失败。
  4. 出队一次

    • head=1count=4,队列为 [ ,84,26,89,45]
    • 打印结果:84<-26<-89<-45

优缺点

优点

  • 高效利用固定内存空间,避免假溢出。
  • 入队和出队的时间复杂度均为 ​O(1)
  • 适用于需要严格限制内存的场景(如嵌入式系统、实时系统)。

缺点

  • 需要预先分配固定大小,扩容困难。
  • 空和满的判定需谨慎处理,容易出错。

应用场景

  1. 缓冲区管理:如键盘输入缓存、网络数据包缓冲。
  2. 任务调度:操作系统中的进程就绪队列。
  3. 生产者-消费者模型:多线程环境下高效传递数据。
  4. 循环任务队列:如打印机任务队列、消息队列。

STL(标准模板库)中没有直接提供固定容量的循环队列​(Circular Queue)实现,但可以通过组合现有容器(如 vector 或 deque)及索引管理来模拟循环队列的特性。以下是具体说明和实现示例:

使用vector底层容器实现

通过 vector 存储元素,并用 head 和 tail 索引标记队列的起止位置,利用模运算实现循环。 

这个程序实现了一个循环队列(cirqueue),使用C++的模板类和vector作为底层容器。以下是对程序的详细分析:


程序结构
  1. 主函数(文档1)​:

    • 创建容量为5的整型循环队列。
    • 连续入队4个元素(62, 84, 26, 89),打印队列。
    • 继续尝试入队45(成功)和46(失败,队列已满),再次打印。
    • 执行一次出队操作,打印最终队列。
  2. 循环队列实现(文档2)​:

    • 使用vector存储元素,维护head(队首索引)、tail(下一个插入位置)、count(当前元素数量)和capacity(队列容量)。
    • 提供enqueue(入队)、dequeue(出队)、isempty(判空)和printqueue(打印队列)方法。

核心逻辑分析

1. ​构造函数

explicit cirqueue(size_t capacity) : vec(capacity), head(0), tail(0), count(0), capacity(capacity) {}
  • 初始化vector大小为capacity,元素默认初始化(对于int可能为未定义值)。
  • headtail初始为0,count记录当前元素数量。

2. ​入队操作(enqueue)​

void enqueue(T text) {if (count == capacity) {cout << "" << endl; // 应输出明确提示,如"Queue is full"return;}vec[tail] = text;tail = (tail + 1) % capacity;count++;
}
  • 队列满条件count == capacity
  • 元素插入到tail位置,tail循环后移。
  • 当队列满时,拒绝新元素并输出空提示(需改进)。

3. ​出队操作(dequeue)​

void dequeue() {if (count == 0) {cout << "" << endl; // 应输出明确提示,如"Queue is empty"return;}head = (head + 1) % capacity;count--;
}
  • 队列空条件count == 0
  • 移动head指针,不实际删除元素,仅减少count

4. ​打印队列(printqueue)​

void printqueue() {for (auto i = 0; i < count; ++i) {auto k = (i + head) % capacity;cout << vec[k];if (i != count - 1) cout << "<-";}cout << endl;
}
  • 按逻辑顺序(从head开始)遍历count个元素,用<-连接。

主函数执行流程

  1. 初始状态:

    • head=0tail=0count=0capacity=5.
    • vector初始值为未定义的int(可能为随机值)。
  2. 四次入队(62, 84, 26, 89)​:

    • tail依次移动到4,count=4
    • 打印结果:62<-84<-26<-89
  3. 第五次入队(45)​:

    • vec[4] = 45tail=0count=5(队列满)。
    • 打印结果:62<-84<-26<-89<-45
  4. 第六次入队(46)​:

    • 队列已满,操作失败,无提示(需改进)。
  5. 一次出队:

    • head移动到1,count=4
    • 打印结果:84<-26<-89<-45

主函数测试

#include"cirqueue.h"
int main() {cirqueue<int>que(5);que.enqueue(62);que.enqueue(84);que.enqueue(26);que.enqueue(89);que.printqueue();que.enqueue(45);que.enqueue(46);que.printqueue(); que.dequeue();que.printqueue();

 输出结果:

 deque为底层容器实现

通过限制 deque 的最大容量并在队列满时删除旧元素:

#include <deque>template<typename T>
class FixedSizeQueue {
public:explicit FixedSizeQueue(size_t max_size) : max_size(max_size) {}void push(T value) {if (dq.size() == max_size) {dq.pop_front(); // 满时删除队首}dq.push_back(value);}// 其他接口与 std::queue 类似private:std::deque<T> dq;size_t max_size;
};

性能对比

实现方式入队/出队时间复杂度内存连续性是否支持动态扩容
基于 vectorO(1)连续
基于 dequeO(1)分段连续否(手动限制)
boost::circular_bufferO(1)连续

如何选择?

  • 需要严格内存控制:用 vector + 环形索引(方法 1)。
  • 需要动态扩容:使用 boost::circular_buffer
  • 简单场景:基于 deque 手动限制容量(方法 2)。

如果追求 STL 的纯粹性,推荐自己实现方法 1;若允许使用第三方库,直接采用 Boost 的实现更高效且功能完整。

关键字:广州市白云区疫情_如何制作app图标_西安关键词排名推广_短视频关键词seo优化

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: