C++泛化双端队列
循环双端队列
双端队列可以在队首和队尾进行入队操作、出队操作的特殊队列。
循环双端队列是充分利用空间,使用格外的数据存储队头和队尾,这里利用数组进行实现。
循环双端队列(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++泛化双端队列的更多相关文章
- lintcode二叉树的锯齿形层次遍历 (双端队列)
题目链接: http://www.lintcode.com/zh-cn/problem/binary-tree-zigzag-level-order-traversal/ 二叉树的锯齿形层次遍历 给出 ...
- lintcode 滑动窗口的最大值(双端队列)
题目链接:http://www.lintcode.com/zh-cn/problem/sliding-window-maximum/# 滑动窗口的最大值 给出一个可能包含重复的整数数组,和一个大小为 ...
- STL---deque(双端队列)
Deque是一种优化了的.对序列两端元素进行添加和删除操作的基本序列容器.它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结 ...
- hdu-5929 Basic Data Structure(双端队列+模拟)
题目链接: Basic Data Structure Time Limit: 7000/3500 MS (Java/Others) Memory Limit: 65536/65536 K (Ja ...
- HDU 4286 Data Handler --双端队列
题意:有一串数字,两个指针,然后一些添加,删除,反转,以及移动操作,最后输出序列. 解法:可以splay做,但是其实双端队列更简便. 维护三个双端队列LE,MI,RI分别表示[L,R]序列左边,[L, ...
- 双端队列(单调队列)poj2823 区间最小值(RMQ也可以)
Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 41844 Accepted: 12384 ...
- Java 集合深入理解(10):Deque 双端队列
点击查看 Java 集合框架深入理解 系列, - ( ゜- ゜)つロ 乾杯~ 什么是 Deque Deque 是 Double ended queue (双端队列) 的缩写,读音和 deck 一样,蛋 ...
- BZOJ2457 BeiJing2011 双端队列
[问题描述] Sherry现在碰到了一个棘手的问题,有N个整数需要排序. Sherry手头能用的工具就是若干个双端队列. 她需要依次处理这N个数,对于每个数,Sherry能做以下两件事 ...
- Fork/Join框架之双端队列
简介 ForkJoinPool管理着ForkJoinWorkerThread线程,ForkJoinWorkerThread线程内部有一个双端队列,这个双端队列主要由一个数组queue.数组下标queu ...
随机推荐
- Elasticsearch-URL查询实例解析
ES(elasticsearch),以下简称ES ES的查询有query.URL两种方式,而URL是比较简洁的一种,本文主要以实例探讨和总结URL的查询方式 1.语法 curl [ -s][ -g][ ...
- 查询AD中被锁定的账号并进行解锁
1:查询AD中被锁定的账号: Search-ADAccount -LockedOut | export-csv -path c:\aaavvv.csv 2:解除锁定 Search-ADAccount ...
- centos jdk
yum list java* yum install xxx -y java -version /* 可省略 */ vi /etc/profile export JAVA_HOME=/usr/lib/ ...
- 3dmax2012卸载/安装失败/如何彻底卸载清除干净3dmax2012注册表和文件的方法
3dmax2012提示安装未完成,某些产品无法安装该怎样解决呢?一些朋友在win7或者win10系统下安装3dmax2012失败提示3dmax2012安装未完成,某些产品无法安装,也有时候想重新安装3 ...
- sql语句查询成绩表各科前三名
--语法形式: ROW_NUMBER() OVER(PARTITION BY COL1 ORDER BY COL2) --解释: 根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示 ...
- Java反射的实例
JAVA反射机制是在运行状态中,对于任意一个类,都能够得到这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法; 这种动态获取的信息以及动态调用对象的方法的功能称为ja ...
- input系统——android input系统
AndroidInput系统--JNI NativeInputManager InputManger InputReader AndroidInput系统--InputReader AndroidIn ...
- 解决jar包冲突
参考文档: http://www.jianshu.com/p/100439269148 idea plugin: https://www.cnblogs.com/huaxingtianxia/p/57 ...
- tomcat——nginx负载均衡
Tomcat一般应用在这种小型系统中应用非常广泛,是开发调试jsp的首先应用.Tomcat和其他web软甲一样具有解析HTML语言的功能,但是处理效率远不及Apacge和Nginx,所以Tomcat一 ...
- 我是青年你是良品-魅蓝NOTE 2
2" title="我是青年你是良品-魅蓝NOTE 2"> 明天魅蓝即将迎来自己的新品发布会.选择儿童节的第二天后最喜爱的手机品牌.让其成为真正青年的良品. 在 ...