0
点赞
收藏
分享

微信扫一扫

温故而知新->数据结构->循环队列->程序实现2_利用类

闲云困兽 2022-01-24 阅读 115

循环队列 ~ 程序实现二

本篇博客的内容为利用 C++ 中的 对数据结构中的 循环队列 进行代码实现!

其中涉及了循环队列的 (入队)(出队)(队头与队尾元素)改(没写(~ ̄▽ ̄)~),判空,判满,打印等操作!并附带了实例以及对应的运行结果!

注意1:在下述程序中尝试了 两种情况

  1. 当队列满时,无法继续入队操作;
  2. 当队列满时,可以继续入队操作,但会覆盖队列满时的队头元素,从而队头指针(_front)会依次后移。

注意2:下面程序中设定循环队列的元素数是5(有效元素个数),但对应于 温故而知新 -> 数据结构 -> 线性表 ->队列 中所说的循环队列,其总的个数为6,只不过1个为空,即可根据 rear + 1 == front 来区别队列是否为满!

具体内容如下
(1)CQueue.h

#pragma once;
#include<iostream>
using namespace std;
#include<assert.h>

typedef int CQDataType;

class CircularQueue
{
public:
	CircularQueue(int capa)
	{
		_data = (CQDataType*)malloc(sizeof(CQDataType)*capa);
		_capa = capa;
		_front = _rear = 0;
		_size = 0;
	}
	~CircularQueue()
	{
		if (_data != NULL)
		{
			free(_data);
		}
	}

	/* 判空操作 */
	bool CQueueEmpty();
	/* 判满操作 */
	bool CQueueFull();

	/* 入队操作 */
	void CQueuePush(CQDataType val);
	/* 出队操作 */
	void CQueuePop();

	/* 获得队头元素 */
	CQDataType CQueueFront();
	/* 获得队尾元素 */
	CQDataType CQueueRear();

	/* 打印操作 */
	void CQueuePrint();
	/* 销毁操作 */
	void CQueueDestory();

private:
	//队头元素的位置
	int _front;
	//队尾元素的下一位置
	int _rear;
	//所存元素个数  最后一个元素的位置是k
	int _capa;//元素计数时,是从0开始的
	//所存元素的首地址
	int *_data;
	//当前有效元素个数
	int _size;
};

(2)main.cpp

#include"CQueue.h"

/*
	整个程序我实验两种情况:
	1、当队列满后,若没有进行出队操作,则不可再往里放数据
	2、当队列满后,且没有出队操作,此时再做入队操作时,会覆盖原有数据,且_front按次序后移
*/

/* 判空操作 */
bool CircularQueue::CQueueEmpty()
{
	return _size == 0;
}
/* 判满操作 */
bool CircularQueue::CQueueFull()
{
	//return (_rear + 1) % (_capa + 1) == _front;
	return _size == _capa; //正常情况下,即满队列不再入队数据
}

/* 入队操作 */
void CircularQueue::CQueuePush(CQDataType val)
{
	/* 情况1 */
	 判断队列是否为满
	//assert(!CircularQueue::CQueueFull());
	 队尾入队
	//_data[_rear++] = val;
	判断队尾是否越界,越界则重置 -- 如此会满足当队列满了后,新数据会覆盖原数据,且队头元素后移
	//if (_rear >= _capa)//说明尾指针到了头指针的位置
	//	_rear = 0;
	//_size++;// 一直入队操作,则_size很容易大于_capa,此时作取余操作可得具体到那个位置

	/* 情况2 */
	//判断队列是否为满
	if (CircularQueue::CQueueFull())
		_front++;//因为满队列后,再入队相当于覆盖了之前的数据,所以队头后移
	_rear = _rear % _capa;
	// 队尾入队
	_data[_rear] = val;

	_rear++;
	_size = _size >= _capa ? _capa : _size + 1;// 一直入队操作,则_size很容易大于_capa,当满队后,_size就不再发生变化
	
}
/* 出队操作 */
void CircularQueue::CQueuePop()
{
	// 判断队列是否为空
	assert(!CircularQueue::CQueueEmpty());
	// 队头出队
	_front++;
	// 判断队头是否越界
	if (_front >= _capa)
		_front = 0;
	_size--;
}

/* 获得队头元素 */
CQDataType CircularQueue::CQueueFront()
{
	assert(!CircularQueue::CQueueEmpty());
	return _data[_front];
}
/* 获得队尾元素 */
CQDataType CircularQueue::CQueueRear()
{
	assert(!CircularQueue::CQueueEmpty());
	if (_rear != 0)
		return _data[_rear - 1];//元素个数从0开始
	else
		return _data[_capa - 1];//_rear=0 即队尾在数组的末尾
}

/* 打印操作 */
void CircularQueue::CQueuePrint()
{
	/* 情况1 */
	/*assert(!CircularQueue::CQueueEmpty());
	int begin = _front;
	int end = _rear == 0 ? _rear + _capa : _rear;
	cout << "队列内容:";
	while (begin < end)
	{
		cout << _data[begin] << " ";
		begin++;
	}cout << endl;*/

	/* 情况2 */
	assert(!CircularQueue::CQueueEmpty());
	int begin = _front;
	//int end = _rear <= _front ? _capa : _rear;
	int end = _rear%_capa <= _front ? _capa : _rear%_capa;
	cout << "队列内容:";
	while (begin < end)
	{
		cout << _data[begin] << " ";
		begin++;
	}
	if (_rear%_capa <= _front)
	{
		begin = 0;
		end = _rear%_capa;
		while (begin < end)
		{
			cout << _data[begin] << " ";
			begin++;
		}
	}
	cout << endl;

}
/* 销毁操作 */
void CircularQueue::CQueueDestory()
{
	free(_data);
	cout << "已销毁" << endl;
}

void test()
{
	/* 情况1 */
	//CircularQueue cq(5);//有效数据个数为5
	///* 验证未超过有效数据个数 即 _rear <= _capa*/
	//cq.CQueuePush(1);
	//cq.CQueuePush(2);
	//cq.CQueuePush(3);
	//cq.CQueuePush(4);
	//cq.CQueuePrint();// 1 2 3 4
	//cout << endl;

	///* 验证 _rear > _capa */
	//cq.CQueuePush(5);
	//cq.CQueuePrint();// 1 2 3 4 5
	cq.CQueuePush(6);// 到此处会警告,因为队列满了,注释掉 push 中的判满操作可解决,如此满队后队列一开始的数据会刷新
	cq.CQueuePrint();
	//cout << endl;

	///* 验证出队 */
	//cq.CQueuePop();
	//cq.CQueuePrint();// 2 3 4 5
	//cq.CQueuePop();
	//cq.CQueuePrint();// 3 4 5
	//cq.CQueuePop();
	//cq.CQueuePrint();// 4 5
	cq.CQueuePop();
	cq.CQueuePrint();// 5
	cq.CQueuePop();
	cq.CQueuePrint();// 到此处依然会警告,因为队列已空
	//cout << endl;

	///* 验证队头、队尾 */
	//cout << "此时队头元素:" << cq.CQueueFront() << endl;		//4
	//cout << "此时队尾元素:" << cq.CQueueRear() << endl << endl;//5

	cq.CQueueDestory();//这句省略,因为析构函数中会重新释放,若还有这句,会报错

	/* 情况2 */
	CircularQueue cq(5);//有效数据个数为5
	/* 验证未超过有效数据个数 即 _rear <= _capa*/
	cq.CQueuePush(1);
	cq.CQueuePush(2);
	cq.CQueuePush(3);
	cq.CQueuePush(4);
	cq.CQueuePrint();// 1 2 3 4
	cout << endl;

	/* 验证 _rear > _capa */
	cq.CQueuePush(5);
	cq.CQueuePrint();// 1 2 3 4 5
	cq.CQueuePush(6);
	cq.CQueuePrint();// 2 3 4 5 6
	cq.CQueuePush(7);
	cq.CQueuePrint();// 3 4 5 6 7
	cout << endl;

	/* 验证出队 */
	cq.CQueuePop();
	cq.CQueuePrint();// 4 5 6 7
	cq.CQueuePop();
	cq.CQueuePrint();// 5 6 7
	cq.CQueuePop();
	cq.CQueuePrint();// 6 7
	//cq.CQueuePop();
	//cq.CQueuePrint();// 7
	//cq.CQueuePop();
	//cq.CQueuePrint();// 到此处依然会警告,因为队列已空
	cout << endl;

	/* 验证队头、队尾 */
	cout << "此时队头元素:" << cq.CQueueFront() << endl;		//6
	cout << "此时队尾元素:" << cq.CQueueRear() << endl << endl;//7

}

int main()
{
	test();
	system("pause");
	return 0;
}

(3)运行结果

  1. 情况1
    在这里插入图片描述

  2. 情况2
    在这里插入图片描述

举报

相关推荐

0 条评论