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 ...
随机推荐
- SSID
无线网络中SSID,是路由器发送的无线信号的名字!如果你将你的无线路由器的SSID:命名为:gouwancheng ,那么当你的无线路由器开启,并启用了无线功能,和允许了SSID广播,那么你就可以轻易 ...
- Linux使用/proc/stat计算CPU使用率
在Linux下,CPU利用率分为用户态,系统态和空闲态,分别表示CPU处于用户态执行的时间,系统内核执行的时间,和空闲系统进程执行的时间,三者之和就是CPU的总时间,当没有用户进程.系统进程等需要执行 ...
- Windows_Management_Instrumentation
WMI是管理系统中的核心 使用本工具的前提是:系统的服务列表中,Windows_Management_Instrumentation(winmgmts)这个服务处于运行状态.如果处于关闭状态,请在运行 ...
- aclocal-1.13: command not found
原因: 将编译好的工程拷贝到系统版本不一样的系统中,再进行编译会出现此类问题. 解决方法: yum install automake autoconf yum install libtool auto ...
- 《C程序设计语言》练习 1-8,1-9
#include <stdio.h> /*编写一个统计空格,制表符与换行符个数的程序*/ main() { int a,b,c,d;//a表示空格个数,b表示制表符个数,c表示换行符个数 ...
- 103)PHP,递归读取目录内容
知识点总结: 打开某个目录 依次读取目录内文件 如果某个文件为目录 递归对该目录采用打开,读取,若还是目录,继续判断,读取 递归点: 如果子文件为目录,则递归 出口: 如果目录中不存在子目录,则不需要 ...
- 吴裕雄--天生自然python学习笔记:打开文件并显示文件内容
Win32com 组件打开文件通过 Documents 的 Open 方法,语法为 : 例如,打开上一节创建的 testl . docx 文件 , 文件变量名为 doc: 获得文件内容的方法有两种,第 ...
- By virtue of|sustain|post |scrape off |stretch|access to|take into account of|exploit|hasten|blur |idle|bored her to|account for|accused of|cruelty
By virtue of this superior quality, this product is often sold out of stockin many areas. 我们的产品因其优秀的 ...
- linux openjdk安装
sudo apt-get install openjdk-8-jdk 默认提示是 sudo apt-get install openjdk-8-jre, 这个只有jre https://openjdk ...
- Hadoop什么?
Hadoop是什么?Hadoop是一个开发和运行处理大规模数据的软件平台,是Appach的一个用java语言实现开源软件框架,实现在大量计算机组成的集群中对海量数据进行分布式计算. Hadoop框架中 ...