循环双端队列

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

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

循环双端队列(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

最新文章

  1. Oracle安装部署,版本升级,应用补丁快速参考
  2. 求n!最后一位非零数
  3. log2取整效率测试
  4. 举例详解CSS中的继承
  5. 防止跨域(jsonp详解)
  6. UVa1606 UVaLive3259 FZU1309 HDU1661 POJ2280 ZOJ2390 Amphiphilic Carbon Molecules
  7. java下udp的DatagramSocket 发送与接收
  8. Hadoop 的常用组件一览
  9. HorizontalScrollView做页卡的一个小记录
  10. windows下Eclipse操作MapReduce例子报错:Failed to set permissions of path: \tmp\hadoop-Jerome\mapred\staging\
  11. Eureka的基本功能和用法
  12. Docker 核心技术之容器
  13. SSH框架新线程下执行数据库持久化时 No Session found for current thread
  14. 用C++实现半透明按钮控件(PNG,GDI+)
  15. Unity3d之表情动画--眨眼
  16. oracle 11g SKIP_UNUSABLE_INDEXES参数
  17. Consul集群搭建
  18. How to export data from Thermo-Calc 如何从Thermo-calc导出文本数据
  19. 【LG4067】[SDOI2016]储能表
  20. C++里创建 Trie字典树(中文词典)(二)(插入、查找、导入、导出)

热门文章

  1. IO概念和五种IO模型
  2. WebService客户端生成方法
  3. iOS涂色涂鸦效果、Swift仿喜马拉雅FM、抽屉转场动画、拖拽头像、标签选择器等源码
  4. ionic2踩坑之订阅发布模式的实现
  5. java第二节课 java语法基础动手动脑
  6. relieved|auction|calculate|campaign|charge for |chartered
  7. verilog乘法器的设计
  8. [LC] 268. Missing Number
  9. [LC] 165. Compare Version Numbers
  10. Spring:使用Spring AOP时,如何获取目标方法上的注解