循环双端队列

双端队列可以在队首和队尾进行入队操作、出队操作的特殊队列。

循环双端队列是充分利用空间,使用格外的数据存储队头和队尾,这里利用数组进行实现。

循环双端队列(CircleQueue.h)

/*************************************************************************
> File Name : CircleDeque.h
> Author : Harold
> Mail : 2106562095@qq.com
> Github : www.github.com/Haroldcc
> Created Time : 2020年03月07日 13时21分25秒
************************************************************************/
#ifndef CIRCLEQUEUE_H_
#define CIRCLEDEQUE_H_
#include <iostream>
#include <sstream>
#include "./myExceptions.h"
/***** 循环双端队列 *****/
/* 利用数组进行实现
* 双端队列:表示头部和尾部都可以进行出入队操作
*/
template <typename T>
class CircleDeque
{
private:
int front; // 队头
int size; // 队内元素个数
T *elements; // 实现队列的数组
int m_capacity; // 数组容量 // 验证数组的容量,是否需要进行数组扩容
void ensureCapacity(int capacity);
// 传入队列中的索引,映射到数组上获取数组上的索引
int index(int index); public:
// 构造函数
CircleDeque(int initialCapacity = 10);
// 析构函数
~CircleDeque() { delete[] this->elements; } int Size() const { return this->size; }
bool isEmpty() const { return this->size == 0; }
// 队尾入队
void enQueueRear(const T &element);
// 队头出队
T deQueueFront();
// 队头入队
void enQueueFront(const T &element);
// 队尾出队
T deQueueRear();
// 获取队头
T &head() const;
// 获取队尾
T &tail() const;
// 清空队列
void clear(); // 输出结果
void output(std::ostream &out) const;
}; // 验证数组的容量,是否需要进行数组扩容
template <typename T>
void CircleDeque<T>::ensureCapacity(int capacity)
{
int oldCapacity = this->m_capacity;
if (oldCapacity >= capacity)
{
return;
} int newCapacity = oldCapacity + (oldCapacity >> 1);
T *newElements = new T[newCapacity];
for (int i = 0; i < this->size; i++)
{
newElements[i] = elements[index(i)];
}
delete[] this->elements;
this->elements = newElements;
this->front = 0;
this->m_capacity = newCapacity;
} // 传入队列中的索引,映射到数组上获取数组上的索引
template <typename T>
int CircleDeque<T>::index(int index)
{
index += this->front;
if (index < 0)
{
return index + this->m_capacity;
}
return index % this->m_capacity;
} // 构造函数
template <typename T>
CircleDeque<T>::CircleDeque(int initialCapacity)
{
if (initialCapacity < 1)
{
std::ostringstream s;
s << "初始化容量 = " << initialCapacity << "必须 > 0";
throw illegalParameterValue(s.str());
}
this->front = 0;
this->size = 0;
this->elements = new T[initialCapacity];
this->m_capacity = initialCapacity;
} // 队尾入队
template <typename T>
void CircleDeque<T>::enQueueRear(const T &element)
{
ensureCapacity(this->size + 1); this->elements[index(this->size)] = element;
this->size++;
} // 队头出队
template <typename T>
T CircleDeque<T>::deQueueFront()
{
T frontElement = this->elements[this->front];
this->elements[this->front] = 0;
this->front = index(1);
this->size--;
return frontElement;
} // 队头入队
template <typename T>
void CircleDeque<T>::enQueueFront(const T &element)
{
ensureCapacity(this->size + 1); this->front = index(-1);
this->elements[this->front] = element;
this->size++;
} // 队尾出队
template <typename T>
T CircleDeque<T>::deQueueRear()
{
int rearIndex = index(this->size - 1);
T rear = this->elements[rearIndex];
this->elements[rearIndex] = 0;
this->size--; return rear;
} // 获取队头
template <typename T>
T &CircleDeque<T>::head() const
{
return this->elements[this->front];
} // 获取队尾
template <typename T>
T &CircleDeque<T>::tail() const
{
return this->elements[index(this->size - 1)];
} // 清空队列
template <typename T>
void CircleDeque<T>::clear()
{
for (int i = 0; i < this->size; i++)
this->elements[index(i)] = 0;
this->size = this->front = 0;
} // 输出结果
template <typename T>
void CircleDeque<T>::output(std::ostream &out) const
{
out << "capacity = " << this->m_capacity << " size = " << this->size
<< " front = " << this->front << ", [";
for (int i = 0; i < this->m_capacity; i++)
{
if (i != 0)
out << ", "; out << this->elements[i];
}
out << "]";
}
template <typename T>
std::ostream &operator<<(std::ostream &out, const CircleDeque<T> &queue)
{
queue.output(out);
return out;
} #endif

测试(testCircleQueue.cpp)

/*************************************************************************
> File Name : testCircleDeque.cpp
> Author : Harold
> Mail : 2106562095@qq.com
> Github : www.github.com/Haroldcc
> Created Time : 2020年03月07日 15时49分27秒
************************************************************************/ #include "CircleDeque.h"
#include <iostream> using namespace std; int main()
{
CircleDeque<int> qu;
// 8 7 6 5 4 3 2 1 101 102 103 104 105 106 107 108 109尾
for (int i = 0; i < 10; i++)
{
qu.enQueueFront(i + 1);
qu.enQueueRear(i + 100);
} cout << qu << endl; for (int i = 0; i < 3; i++)
{
qu.deQueueFront();
qu.deQueueRear();
} qu.enQueueFront(11);
qu.enQueueFront(12);
cout << qu << endl;
while (!qu.isEmpty())
{
cout << qu.deQueueFront() << endl;
} return 0;
}

输出

capacity = 22 size = 20 front = 20, [8, 7, 6, 5,
4, 3, 2, 1, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, -1163005939, -1163005939, 10, 9]
capacity = 22 size = 16 front = 21, [11, 7, 6, 5, 4, 3, 2, 1, 100, 101, 102, 103, 104, 105, 106, 0, 0, 0, -1163005939, -1163005939, 0, 12]
12
11
7
6
5
4
3
2
1
100
101
102
103
104
105
106

C++泛化双端队列的更多相关文章

  1. lintcode二叉树的锯齿形层次遍历 (双端队列)

    题目链接: http://www.lintcode.com/zh-cn/problem/binary-tree-zigzag-level-order-traversal/ 二叉树的锯齿形层次遍历 给出 ...

  2. lintcode 滑动窗口的最大值(双端队列)

    题目链接:http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑动窗口的最大值 给出一个可能包含重复的整数数组,和一个大小为  ...

  3. STL---deque(双端队列)

    Deque是一种优化了的.对序列两端元素进行添加和删除操作的基本序列容器.它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结 ...

  4. hdu-5929 Basic Data Structure(双端队列+模拟)

    题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others)    Memory Limit: 65536/65536 K (Ja ...

  5. HDU 4286 Data Handler --双端队列

    题意:有一串数字,两个指针,然后一些添加,删除,反转,以及移动操作,最后输出序列. 解法:可以splay做,但是其实双端队列更简便. 维护三个双端队列LE,MI,RI分别表示[L,R]序列左边,[L, ...

  6. 双端队列(单调队列)poj2823 区间最小值(RMQ也可以)

    Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 41844   Accepted: 12384 ...

  7. Java 集合深入理解(10):Deque 双端队列

    点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...

  8. BZOJ2457 BeiJing2011 双端队列

    [问题描述] Sherry现在碰到了一个棘手的问题,有N个整数需要排序.  Sherry手头能用的工具就是若干个双端队列.        她需要依次处理这N个数,对于每个数,Sherry能做以下两件事 ...

  9. Fork/Join框架之双端队列

    简介 ForkJoinPool管理着ForkJoinWorkerThread线程,ForkJoinWorkerThread线程内部有一个双端队列,这个双端队列主要由一个数组queue.数组下标queu ...

随机推荐

  1. A. Coffee Break(思维题,类似于邻接表的head数组用法)

    题:https://codeforces.com/gym/101911/problem/A 题意:每天工作m分钟,每次喝coffee得间隔d分钟,然后给出n个数,每个数表示想在一天中的a[i]的时刻喝 ...

  2. kubectl格式化输出和调试

    1.格式化输出 以特定的格式想终端输出详细信息,可以在 kubectl 命令中添加 -o  或者 -output 选项 输出格式 描述 -o=custom-columns=<spec> 使 ...

  3. Android recycleview item水波纹效果

    item的xml 根标签下添加如下三个属性 android:clickable="true" android:focusable="true" android: ...

  4. Smarty使用-模版中编写js

      在smarty模版中编写js使用literal标签, Literal 标签区域内的数据将被当作文本处理,此时模板将忽略其内部的所有字符信息. 该特性用于显示有可能包含大括号等字符信息的 javas ...

  5. MySQL数据库优化、设计与高级应用

    MySQL数据库优化主要涉及两个方面,一方面是对SQL语句优化,另一方面是对数据库服务器和数据库配置的优化. 数据库优化 SQL语句优化 为了更好的看到SQL语句执行效率的差异,建议创建几个结构复杂的 ...

  6. 高可用(keepalived+lvs)

    博主本人平和谦逊,热爱学习,读者阅读过程中发现错误的地方,请帮忙指出,感激不尽 架构图: 本次实验严格按照下图完成 1.系统环境设置 1.1SELinux设置 vim /etc/selinux/con ...

  7. particlesJS is not defined

    插件或者js文件在引入时需要注意引入顺序,每次都找很久的错误 一般引入min.js就可以,min.js意思就是压缩的js文件 引入时应该先加入min类的文件在引入配置文件 比如particles插件, ...

  8. java和javac命令

    记录一下,今天无意中用到单独编译和执行某个java类,遇到各种Error: Could not find or load main class等问题,解决方案如下其中2和3选其一试试~ 1.javac ...

  9. deeplearning.ai 神经网络和深度学习 week1 深度学习概论

    1. 预测房价.广告点击率:典型的神经网络,standard NN. 图像:卷积神经网络,CNN. 一维序列数据,如音频,翻译:循环神经网络,RNN. 无人驾驶,涉及到图像.雷达等更多的数据类型:混合 ...

  10. [LC] 485. Max Consecutive Ones

    Given a binary array, find the maximum number of consecutive 1s in this array. Example 1: Input: [1, ...