循环双端队列实际上就是是在之前单向的循环队列的基础上可以进行两端添加、删除操作的循环队列,因此我们在函数中增加了头部入队和尾部删除。
而对于队尾元素没必要再设置一个变量,因为尾部的变量直接可以用front+size
下面是 Circle_Double_Queue.h
的代码。
#pragma once
#include <iostream>
using namespace std;
template <class E>
class Circle_Double_Queue
{
private:
int size;
int front;
E* elements;
int ELEMENT_LENGTH = 10;
int sum_capacity;
void Ensure_Capacity(int capacity);
int find_index(int index);
public:
Circle_Double_Queue() //默认构造函数
{
size = 0;
front = 0;
elements = new E[ELEMENT_LENGTH]; //默认长度为10
sum_capacity = ELEMENT_LENGTH;
}
int cau_size(); //求数据队列长度
bool isEmpty(); //检测是否为空
void enQueue_Front(E element); //头部入队
E deQueue_Front(); //头部出队
void enQueue_Last(E element); //尾部入队
E deQueue_Last(); //尾部出队
E look_front(); //观测队头元素
E look_last(); //观测队尾元素
void print();
~Circle_Double_Queue() {};
};
下面是 Circle_Double_Queue.cpp
的代码。
#include "Circle_Double_Queue.h"
template <class E>
int Circle_Double_Queue<E>::cau_size() //求循环队列长度
{
return size;
}
template <class E>
bool Circle_Double_Queue<E>::isEmpty() //判断队列是否为空
{
return size == 0;
}
template <class E>
void Circle_Double_Queue<E>::enQueue_Front(E element) //头部入队
{
Ensure_Capacity(size + 1);
front = find_index(-1);
elements[front] = element;
size++;
}
template <class E>
void Circle_Double_Queue<E>::enQueue_Last(E element) //尾部入队
{
Ensure_Capacity(size + 1);
elements[find_index(size)] = element; //利用find_index()函数来找到尾部元素在哪
size++;
}
template <class E>
E Circle_Double_Queue<E>::deQueue_Front() //头部出队
{
E front_element = elements[front];
elements[front] = NULL;
front = (front + 1) % sum_capacity; //若队头已移至数组尾部,对其取余,到数组头部
size--;
return front_element;
}
template <class E>
E Circle_Double_Queue<E>::deQueue_Last() //尾部出队
{
int rearIndex = find_index(size - 1);
E rear = elements[rearIndex];
elements[rearIndex] = NULL;
size--;
return rear;
}
template <class E>
E Circle_Double_Queue<E>::look_front() //观测队头元素
{
return elements[front];
}
template <class E>
E Circle_Double_Queue<E>::look_last() //观测队尾元素
{
return elements[find_index(size - 1)];
}
template <class E>
void Circle_Double_Queue<E>::print() //打印所有元素
{
int n = size;
for (int i = 0; i < n; i++)
{
cout << elements[find_index(i)] << " ";
}
cout << endl;
/*for (int i = 0; i < n; i++) //此处代码用来观测数组中的i对应元素,以此来调试代码
{
cout << elements[i] << " ";
}
cout << endl;*/
}
template <class E>
void Circle_Double_Queue<E>::Ensure_Capacity(int capacity) //检测容量
{
int Old_capacity = sum_capacity;
if (Old_capacity >= capacity)
{
return;
}
int New_capacity = (Old_capacity + (Old_capacity >> 1)); //新数组的内存扩充为原有数组的1.5倍数
E* new_elements = new E[New_capacity];
for (int i = 0; i < size; i++)
{
new_elements[i] = elements[find_index(i)];
}
sum_capacity = New_capacity; //需要在上面数组复制后再进行数组容量改变,否则在进行find_index()函数时,index % sum_capacity求余的就是新的容量,会产生位置的错乱
elements = new_elements;
front = 0;//重置front
}
template <class E>
int Circle_Double_Queue<E>::find_index(int index) //找到队列中index所对应动态数组中的数组元素 对index=(i + front) % sum_capacity和index<0的情况进行封装
{
index += front;
if (index < 0) //当front=0时,在front前添加元素,index为-1,就把front放在最后
{
return index + sum_capacity;
}
return index % sum_capacity;
}
最后是 mian.cpp
的代码进行测试。
#include <iostream>
#include "Circle_Double_Queue.h"
#include "Circle_Double_Queue.cpp"
int main()
{
Circle_Double_Queue<int> cdque;
cdque.enQueue_Front(1);
cdque.enQueue_Front(2);
cdque.enQueue_Front(3);
cdque.enQueue_Front(4);
cdque.enQueue_Front(5);
cdque.enQueue_Front(6);
cdque.enQueue_Last(11);
cdque.enQueue_Last(22);
cdque.enQueue_Last(33);
cdque.enQueue_Last(44);
cdque.print();
cdque.enQueue_Front(7);
cdque.print();
cdque.enQueue_Last(55);
cdque.print();
cdque.enQueue_Last(66);
cdque.print();
cdque.enQueue_Last(77);
cdque.print();
return 0;
}
代码都经过测试检测,可放心食用~