数据结构之——双向循环队列完备版(C++实现)

循环双端队列实际上就是是在之前单向的循环队列的基础上可以进行两端添加、删除操作的循环队列,因此我们在函数中增加了头部入队和尾部删除。
而对于队尾元素没必要再设置一个变量,因为尾部的变量直接可以用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;
}

代码都经过测试检测,可放心食用~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GXM.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值