双向队列头文件Deq1.h
#include<iostream>
#include<stdlib.h>
#include<stddef.h>
#include<math.h>
#include<algorithm>
using namespace std;
#ifdef __STL_USE_EXCEPTIONS
#define __STL_TRY try
#define __STL_UNWIND(action) catch(...) { action; throw; }
#else
#define __STL_TRY
#define __STL_UNWIND(action)
#endif
inline size_t __deque_buf_size(size_t n, size_t sz)//n用户自定义元素个数
{
return n != 0 ? n : (sz < 512 ? size_t(512 / sz) : size_t(1));//512默认分配512字节
}
template<class T1, class T2>
inline void construct(T1* p, const T2& value)
{
new (p)T1(value);
}
template<class T>
inline void destroy(T* ptr)
{
ptr->~T();
}
template<class ForwardIterator>
inline void destroy(ForwardIterator first, ForwardIterator last)
{
for (; first != last; ++first)
destroy(&*first);
}
//将内存接口包装,以满足STL标准接口
template<class T, class Alloc>
class simple_alloc {
public:
static T* allocate(size_t n)
{
T* result = (T*)malloc(sizeof(T) * n);
if (0 == result) exit(0);
return result;
}
static void deallocate(T* p)
{
free(p);
}
};
//deque iterator
template <class T, class Ref, class Ptr>
struct __deque_iterator {
typedef __deque_iterator<T, T&, T*> iterator;
typedef __deque_iterator<T, const T&, const T*> const_iterator;
static size_t buffer_size() { return __deque_buf_size(0, sizeof(T)); }
// 未继承 std::iterator,所以必须自行撰写五个必要的迭代器相应型别
typedef random_access_iterator_tag iterator_category; // (1)
typedef T value_type; // (2)
typedef Ptr pointer; // (3)
typedef Ref reference; // (4)
typedef size_t size_type;
typedef ptrdiff_t difference_type; // (5)ptrdiff_t long int
typedef T** map_pointer;
typedef __deque_iterator self;
// 保持与容器的联结
T* cur; // 此迭代器所指之缓冲区中的现行
T* first; // 此迭代器所指之缓冲区的头
T* last; // 此迭代器所指之缓冲区的尾(含备用空间)
map_pointer node; // 指向指针数组map
__deque_iterator(T* x, map_pointer y)
: cur(x), first(*y), last(*y + buffer_size()), node(y) {}
__deque_iterator() : cur(0), first(0), last(0), node(0) {}//使用的是这个
__deque_iterator(const iterator& x)
: cur(x.cur), first(x.first), last(x.last), node(x.node) {}
~__deque_iterator(){}
// __deque_iterator<> 重载运算符
reference operator*() const { return *cur; }//*iterator
pointer operator->() const { return &(operator*()); }//iterator->cur
difference_type operator-(const self& x) const {//iter1-iter2
return difference_type(buffer_size()) * (node - x.node - 1) +//块间
(cur - first) + (x.last - x.cur);//块内
}
self& operator++() {//++iter
++cur; // 切换至下一个元素
/*
如果已达所在缓冲区的尾端
就切换至下一个节点(亦即缓冲区)的第一个元素。
*/
if (cur == last) {
set_node(node + 1);
cur = first;
}
return *this;
}
self operator++(int) {//iter++
self tmp = *this;
++* this;
return tmp;
}
self& operator--() {//--iter
/*
如果已达所在缓冲区的头端,就切换至前一个节点(亦即缓冲区)
的最后一个元素。
*/
if (cur == first) {
set_node(node - 1);
cur = last;
}
--cur; // 切换至前一个元素
return *this;
}
self operator--(int) {//iter--
self tmp = *this;
--* this;
return tmp;
}
//实现随机存储。迭代器可以直接跳跃n个距离
//要么直接在cur上面加,当碰到当前片段last,则重新换内存片段,再在cur上面加
self& operator+=(difference_type n) {//iter+n
difference_type offset = n + (cur - first);
if (offset >= 0 && offset < difference_type(buffer_size()))//目标位置在同一缓冲区内
cur += n;
else {
// 目标位置不在同一缓冲区内
difference_type node_offset =
offset > 0 ? offset / difference_type(buffer_size())
: -difference_type((-offset - 1) / buffer_size()) - 1;
// 切换至正确的节点(亦即缓冲区)
set_node(node + node_offset);
// 切换至正确的元素
cur = first + (offset - node_offset * difference_type(buffer_size()));
}
return *this;
}
self operator+(difference_type n) const {//const+
self tmp = *this;
return tmp += n; // 调用operator+=
}
self& operator-=(difference_type n) { return *this += -n; }//iter-=n
// 以上利用operator+= 来完成 operator-=
self operator-(difference_type n) const {
self tmp = *this;
return tmp -= n; // 调用operator-=
}
//随机存取iter[]
reference operator[](difference_type n) const { return *(*this + n); }
// 以上调用operator*, operator+
bool operator==(const self& x) const { return cur == x.cur; }
bool operator!=(const self& x) const { return !(*this == x); }
bool operator<(const self& x) const {
return (node == x.node) ? (cur < x.cur) : (node < x.node);
}
//设置节点信息,在已经分配的连续内存片段上面取值或者存数值
void set_node(map_pointer new_node) {
node = new_node;
first = *new_node;
last = first + difference_type(buffer_size());
}
};
template <class T, class Alloc = allocator<T>>
class deque {
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef size_t size_type;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef ptrdiff_t difference_type;
public:
typedef __deque_iterator<T, T&, T*>iterator;//迭代器类
protected:
typedef pointer* map_pointer;
iterator start;//开始迭代器
iterator finish;//结束迭代器
iterator cur;
map_pointer map;//指针数组map
size_type map_size;//指针数组元素个数
typedef simple_alloc<value_type, Alloc> data_allocator;//连续内存块 内存器
typedef simple_alloc<pointer, Alloc>map_allocator;//指针数组 内存分配器
public:
iterator begin() { return start; }
iterator end() { return finish; }
reference operator[](size_type n) {
return start[difference_type(n)];
}
reference front() { return *start; }
reference back() {
iterator tmp = finish;
--tmp;
return *tmp;
}
size_type size()const { return finish - start; }
size_type max_size()const { return size_type(-1); }
T* allocate_node() { return data_allocator::allocate(buffer_size()); }
static size_t buffer_size() { return __deque_buf_size(0, sizeof(T)); }
static size_t initial_map_size() { return 8; }
bool empty()const { return finish == start; }
void creat_map_and_nodes(size_type num_elements);
void fill_initialize(size_type n, const value_type& value);
void push_back(const value_type& t);
void push_back_aux(const value_type& t);
void push_front(const value_type& t);
void push_front_aux(const value_type& t);
void reserve_map_at_back(size_type nodes_to_add = 1);
void reserve_map_at_front(size_type nodes_to_add = 1);
void reallocate_map(size_type nodes_to_add, bool add_at_front);
void pop_back();
void pop_back_aux();
void pop_front();
void pop_front_aux();
void clear();
iterator erase(iterator first, iterator last);
iterator insert(iterator position, const value_type& x);
iterator insert_aux(iterator pos, const value_type& x);
deque(int n, const value_type& value) :start(), finish(), map(0), map_size(0)
{
fill_initialize(n, value);
}
};
template <class T, class Alloc>
void deque<T, Alloc>::fill_initialize(size_type n, const value_type& value) {
creat_map_and_nodes(n);
map_pointer cur;
__STL_TRY
{
for (cur = start.node; cur < finish.node; ++cur)
uninitialized_fill(*cur,*cur + buffer_size(),value);//初始化节点内存块buffer
uninitialized_fill(finish.first, finish.cur, value);//尾部可能有多余空间
}
}
template <class T, class Alloc>
void deque<T, Alloc>::creat_map_and_nodes(size_type num_elements)
{
size_type num_nodes = num_elements / buffer_size() + 1;//计算nodes个数,用需要的元素总数除以每个buffer的大小,得到map中节点个数
map_size = max(initial_map_size(), num_nodes + 2);//map的大小最小设置成8,要么设置成num_nodes+2的大小,可左右各增长一个
map = map_allocator::allocate(map_size);//map内存分配
map_pointer nstart = map + (map_size - num_nodes) / 2;//先使用map指针数组中间的位置,方便前后扩充
map_pointer nfinish = nstart + num_nodes - 1;
map_pointer cur;
__STL_TRY{
for (cur = nstart; cur <= nfinish; ++cur)
*cur = allocate_node();//始化指针数组成员
}
start.set_node(nstart);
finish.set_node(nfinish);
start.cur = start.first;
finish.cur = finish.first + num_elements % buffer_size();//向最后元素的后面一个元素形成[start , finish)左闭右开空间
}
template <class T, class Alloc>
void deque<T, Alloc>::push_back(const value_type& t)
{
if (finish.cur != finish.last - 1) {//尾部还有一个以上的空间
construct(finish.cur, t);//直接构造
++finish.cur;//调整finish的cur+1
}
else {
push_back_aux(t);//没有或者只剩下一个,添加node,然后构造
}
}
template <class T, class Alloc>
void deque<T, Alloc>::push_back_aux(const value_type& t) {
value_type t_copy = t;
reserve_map_at_back();//加入后是否大于map内存空间
*(finish.node + 1) = allocate_node();//分配节点,node
__STL_TRY{
construct(finish.cur, t_copy);//构造元素
finish.set_node(finish.node + 1);
finish.cur = finish.first;//设定finish
}
__STL_UNWIND(deallocate_node(*(finish.node + 1)));//释放返回
}
template <class T, class Alloc>
void deque<T, Alloc>::push_front(const value_type& t)
{
if (start.cur != start.first) {
construct(start.cur - 1, t);
--start.cur;
}
else
push_front_aux(t);
}
template <class T, class Alloc>
void deque<T, Alloc>::push_front_aux(const value_type& t) {
value_type t_copy = t;
reserve_map_at_front();//是否需要重新分配map
*(start.node - 1) = allocate_node();//分配node
__STL_TRY{
start.set_node(start.node - 1);
start.cur = start.last - 1;
construct(start.cur, t_copy);
}
}
template <class T, class Alloc>
void deque<T, Alloc>::reserve_map_at_back(size_type nodes_to_add)
{
if (nodes_to_add + 1 > map_size - (finish.node - map))
// 如果 map 尾端的节点备用空间不足
// 符合以上条件则必须重换一个map(配置更大的,拷贝原来的,释放原来的)
reallocate_map(nodes_to_add, false);
}
template <class T, class Alloc>
void deque<T, Alloc>::reserve_map_at_front(size_type nodes_to_add)
{
if (nodes_to_add > start.node - map)
// 如果 map 前端的节点备用空间不足
// 符合以上条件则必须重换一个map(配置更大的,拷贝原来的,释放原来的)
reallocate_map(nodes_to_add, true);
}
template <class T, class Alloc>
void deque<T, Alloc>
::reallocate_map(size_type nodes_to_add, bool add_at_front) {
size_type old_num_nodes = finish.node - start.node + 1;//旧节点数
size_type new_num_nodes = old_num_nodes + nodes_to_add;//加上需要新增加的总的节点数
map_pointer new_nstart;
/* 原map_size很充裕时只用调整下start和finish的位置就行了
*此时并不用重新申请map,只需要调整一下位置
*重新将已用的结点挪动到中间位置即可
*/
if (map_size > 2 * new_num_nodes) {
new_nstart = map + (map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);//重新计算start和finish迭代器应处于的位置
if (new_nstart < start.node)
copy(start.node, finish.node + 1, new_nstart);//首部需要往后调整
else//尾部需要往前调整
copy_backward(start.node, finish.node + 1, new_nstart + new_num_nodes);
}
else {
size_type new_map_size = map_size + max_size() + 2;//max(map_size, nodes_to_add) + 2;
// 配置一块空间,准备给新map使用。
map_pointer new_map = map_allocator::allocate(new_map_size);
new_nstart = new_map + (new_map_size - new_num_nodes) / 2
+ (add_at_front ? nodes_to_add : 0);
// 把原map 内容拷贝过来。
copy(start.node, finish.node + 1, new_nstart);
// 释放原map
map_allocator::deallocate(map);
// 设定新map的起始位址与大小
map = new_map;
map_size = new_map_size;
}
// 重新设定迭代器 start 和 finish
start.set_node(new_nstart);
finish.set_node(new_nstart + new_num_nodes - 1);
}
template <class T, class Alloc>
void deque<T, Alloc>::pop_back() {
if (finish.cur != finish.first) {
// 最后缓冲区有一个(或更多)元素
--finish.cur; // 调整指针
destroy(finish.cur); // 将最后元素析构
}
else
// 最后缓冲区没有任何元素
pop_back_aux(); // 这里将进行缓冲区的释放工作
}
// 只有当finish.cur == finish.first时才会被调用。
template <class T, class Alloc>
void deque<T, Alloc>::pop_back_aux() {
deallocate_node(finish.first); // 释放最后一个缓冲区
finish.set_node(finish.node - 1); // 调整 finish 的状态,使指向
finish.cur = finish.last - 1; // 上一个缓冲区的最后一个元素
destroy(finish.cur); // 将该元素析构。
}
template <class T, class Alloc>
void deque<T, Alloc>::pop_front() {
if (start.cur != start.last - 1) {
// 第一缓冲区有一个(或更多)元素
destroy(start.cur); // 将第一元素析构
++start.cur; // 调整指针
}
else
// 第一缓冲区仅有一个元素
pop_front_aux(); // 这里将进行缓冲区的释放工作
}
// 只有当start.cur == start.last - 1时才会被调用。
template <class T, class Alloc>
void deque<T, Alloc>::pop_front_aux() {
destroy(start.cur); // 将第一缓冲区的第一个元素析构。
data_allocator::deallocate(start.first); // 释放第一缓冲区。
start.set_node(start.node + 1); // 调整 start 的状态,使指向
start.cur = start.first; // 下一个缓冲区的第一个元素。}
}
template <class T, class Alloc>
void deque<T, Alloc>::clear() {
// 以下针对头尾以外的每一个缓冲区(它们一定都是饱满的)
for (map_pointer node = start.node + 1; node < finish.node; ++node) {
// 将缓冲区内的所有元素析构。
destroy(*node, *node + buffer_size());
// 释放缓冲区存储器
data_allocator::deallocate(*node);
}
if (start.node != finish.node) { // 至少有头尾两个缓冲区
destroy(start.cur, start.last); // 将头缓冲区的目前所有元素析构
destroy(finish.first, finish.cur); // 将尾缓冲区的目前所有元素析构
// 以下释放尾缓冲区。注意,头缓冲区保留。
data_allocator::deallocate(finish.first);
}
else // 只有一个缓冲区
destroy(start.cur, finish.cur); // 将此唯一缓冲区内的所有元素析构
// 注意,并不释放缓冲区空间。这唯一的缓冲区将保留。
finish = start; // 调整状态
}
template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::erase(iterator first, iterator last) {
if (first == start && last == finish) { // 如果清除区间就是整个 deque
clear(); // 直接调用 clear() 即可
return finish;
}
else {
difference_type n = last - first; // 清除区间的长度
difference_type elems_before = first - start;// 清除区间前方的元素个数
if (elems_before < (size() - n) / 2) { // 如果前方的元素比较少,
copy_backward(start, first, last); // 向后移动前方元素(覆盖清除区间)
iterator new_start = start + n; // 标记 deque 的新起点
destroy(start, new_start); // 移动完毕,将冗余的元素析构
// 以下将冗余的缓冲区释放
for (map_pointer cur = start.node; cur < new_start.node; ++cur)
data_allocator::deallocate(*cur);
start = new_start; // 设定 deque 的新起点
}
else { // 如果清除区间后方的元素比较少
copy(last, finish, first); // 向前移动后方元素(覆盖清除区间)
iterator new_finish = finish - n; // 标记 deque 的新尾点
destroy(new_finish, finish); // 移动完毕,将冗余的元素析构
// 以下将冗余的缓冲区释放
for (map_pointer cur = new_finish.node + 1; cur <= finish.node; ++cur)
data_allocator::deallocate(*cur);
finish = new_finish; // 设定 deque 的新尾点
}
return start + elems_before;
}
}
// 在position 处插入一个元素,其值为 x
template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::insert(iterator position, const value_type& x) {
if (position.cur == start.cur) {// 如果安插点是deque 最前端
push_front(x); // 交给push_front 去做
return start;
}
else if (position.cur == finish.cur) { // 如果安插点是deque 最尾端
push_back(x); // 交给push_back 去做
iterator tmp = finish;
--tmp;
return tmp;
}
else {
return insert_aux(position, x); // 交给 insert_aux 去做
}
}
template <class T, class Alloc>
typename deque<T, Alloc>::iterator deque<T, Alloc>::insert_aux(iterator pos, const value_type& x) {
difference_type index = pos - start; // 插入点之前的元素个数
value_type x_copy = x;
if (index < size() / 2) { // 如果插入点之前的元素个数比较少
push_front(front()); // 在最前端加入与第一元素同值的元素
iterator front1 = start; // 以下标示记号,然后进行元素移动
++front1;
iterator front2 = front1;
++front2;
pos = start + index;
iterator pos1 = pos;
++pos1;
copy(front2, pos1, front1); // 元素移动
}
else { // 插入点之后的元素个数比较少
push_back(back()); // 在最尾端加入与最后元素同值的元素。
iterator back1 = finish; // 以下标示记号,然后进行元素移动
--back1;
iterator back2 = back1;
--back2;
pos = start + index;
copy_backward(pos, back2, back1); // 元素移动
}
*pos = x_copy; // 在插入点上设定新值
return pos;
}
测试代码
#include"Deq1.h"
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
deque<int> ideq(135, 9);//一段连续缓冲区可以存放8个int=32字节初始化内存,并将135个元素初始化为9.
cout << "size = " << ideq.size() << endl;//135 deque上面存储的元素个数
for (int i = 0; i < ideq.size(); ++i)//随机读入
ideq[i] = i;
cout << endl << "读取" << endl;
for (int i = 0; i < ideq.size(); ++i)//输出
{
cout << ideq[i];
cout << ' ';
}
cout << endl;//0 1 2 3 ... 134
ideq.push_back(135);//后端插入
ideq.push_front(0); //前端插入
cout << endl << "前后分别添加元素:" << endl;
for (int i = 0; i < ideq.size(); ++i)//输出
{
cout << ideq[i];
cout << ' ';
}
cout << endl;
ideq.pop_front();
cout << endl << "删除前端的元素:" << endl;
for (int i = 0; i < ideq.size(); ++i)//输出
{
cout << ideq[i];
cout << ' ';
}
cout << endl;
deque<int>::iterator iter = ideq.begin();
cout << "打印第一个元素的值:";
cout << *iter << endl;
iter++;
cout << "右移一位元素:";
cout << *iter << endl;
iter--;
ideq.insert(iter, 8);
cout << endl << "开头插入8" << endl;
for (int i = 0; i < ideq.size(); ++i)//输出
{
cout << ideq[i];
cout << ' ';
}
cout << endl;
ideq.erase(ideq.begin(), iter);
cout << endl << "擦除8" << endl;
for (int i = 0; i < ideq.size(); ++i)//输出
{
cout << ideq[i];
cout << ' ';
}
return 0;
}