您的位置:首页 > 理论基础 > 数据结构算法

数据结构探险——队列篇

2019-05-22 18:23 1321 查看

@这篇文档是由C++代码实现的环形队列

队列就是先进先出的一种数据结构,环形队列只是将队尾元素与队头元素连接在了一起,要记住的就是队头指针永远指向的是存放队头的那个数组的下标,而队尾指针指向的是队尾元素的下一个数组的下标。

本文是以Visual Studio中新建的C++win32的控制台应用程序实现的,其中建立了头文件和源文件以及实现main()的demo文件,分别是MyQueue.h和MyQueue.cpp和demo.cpp文件。

MyQueue.h文件

#ifndef MYQUEUE_H
#define MYQUEUE_H

class MyQueue
{
public:
MyQueue(int queueCapacity);    //队列的构造函数
virtual ~MyQueue();			   //队列的析构函数
void ClearQueue();			   //队列的清空函数
bool QueueEmpty() const;	   //队列的判空函数
bool QueueFull() const;		   //队列的判满函数
int QueueLength() const;	   //队列的求长函数
bool EnQueue(int element);	   //队尾插入元素的函数
bool DeQueue(int &element);	   //队头删除元素的函数或者说取队头元素的函数
bool QueueTraverse();	       //遍历队列的元素的函数
private:
int *m_pQueue;			//队列数组指针
int m_iQueueLen;		//队列元素个数
int m_iQueueCapacity;	//队列数组容量
int m_iHead;			//队列头指针
int m_iTail;			//队列尾指针
};

#endif

MyQueue.cpp

#include "MyQueue.h"
#include <iostream>
using namespace std;

//队列的构造函数
MyQueue::MyQueue(int queueCapacity)
{
m_iQueueCapacity = queueCapacity;	//初始化队列的容量
//m_iHead = 0;						//初始化队列的头指针指向位置
//m_iTail = 0;						//初始化队列的尾指针指向位置
//m_iQueueLen = 0;					//初始化队列的长度
ClearQueue();						//调用ClearQueue()的方法初始化队列,相当于上面的三行代码的操作
m_pQueue = new int[queueCapacity];  //初始化存放队列的数组
}

//队列的析构函数
MyQueue::~MyQueue()
{
delete []m_pQueue;
m_pQueue = NULL;
}

//队列的清空函数
void MyQueue::ClearQueue()
{
m_iHead = 0;						//清空队列的头指针指向位置
m_iTail = 0;						//清空队列的尾指针指向位置
m_iQueueLen = 0;					//清空队列的长度
}

//队列的判空函数
bool MyQueue::QueueEmpty() const
{
if(m_iQueueLen == 0)
{
return true;
}
else
{
return false;
}
//return m_iQueueLen == 0?true:false;  //具有相同的功能

}

//队列的判满函数
bool MyQueue::QueueFull() const
{
return m_iQueueLen ==m_iQueueCapacity?true:false;
}

//获取队列的长度的函数
int MyQueue::QueueLength() const
{
return m_iQueueLen;
}

//队列的插入新元素函数
bool MyQueue::EnQueue(int element)
{
if(QueueFull())
{
cout << "队列已满,不能再插入元素!" << endl;
return false;
}
else
{
//m_pQueue[QueueLength()-1] = element;  //个人的想法,其实QueueLength()-1和m_iTail的值是相同的。
//再思考之后发现他们的值不一样,还是用m_iTail要好一些。
//因为有可能m_iHead=2,m_iTail=0。
//而此时的QueueLength()-1=m_iQueueCapacity-2(环形队列),
//所以不能用QueueLength()-1。
m_pQueue[m_iTail] = element;
m_iTail++;
m_iTail = m_iTail%m_iQueueCapacity;
m_iQueueLen++;
return true;
}
}

//队列删除元素的函数
bool MyQueue::DeQueue(int &element)
{
if(QueueEmpty())
{
cout << "队列为空,不能再取元素!" << endl;
return false;
}
else
{
element = m_pQueue[m_iHead];
m_iHead++;
m_iHead = m_iHead%m_iQueueCapacity;
m_iQueueLen--;
return true;
}
}

//遍历队列的成员的函数
bool MyQueue::QueueTraverse()
{
if(QueueEmpty())
{
cout << "队列为空,遍历不出任何元素!" << endl;
return false;
}
else
{
//存在一个问题就是当m_iHead=3,而m_iQueueLen=2,m_iQueueCapacity=4的时候,
//i肯定是不小于m_iQueueLen的值的,所以不能打印出来队列的成员。
for(int i=m_iHead; i<m_iHead+m_iQueueLen;i++)
{
cout << m_pQueue[i%m_iQueueCapacity] << endl;
cout << endl;
}
return true;
}
}

demo.cpp文件

#include <iostream>
#include <stdlib.h>
#include "Customer.h"
#include "MyQueue.h"
using namespace std;

int main(void)
{
MyQueue *p = new MyQueue(4);		//实例化队列
p->EnQueue(10);						//往新队列里面插入新元素
p->EnQueue(12);
p->EnQueue(16);
p->EnQueue(18);
p->EnQueue(20);

cout << "循环遍历队列:" << endl;		//遍历打印出队列里面的所有元素
p->QueueTraverse();

int e = 1;
p->DeQueue(e);						//删除队列里面的队头元素
cout << endl;
cout << "删除的元素:" << endl;		//打印出删除的队头元素
cout << e <<endl;
cout << endl;

cout << "删除元素后循环遍历队列:" << endl;   	//再次循环遍历队列里面的所有元素
p->QueueTraverse();
cout << endl;

cout << "清空队列后循环遍历队列:" << endl;	//调用队列的清空队列的函数,并再次遍历队列里面的元素
p->ClearQueue();
p->QueueTraverse();

cout << endl;							//清空队列之后,再次往队列里面添加新的元素,并且重新遍历队列里面的新元素
p->EnQueue(50);							//这个操作让我想到删除硬盘上的东西是不是只是移动了指针,
//而没有真正的删除已存储的东西。如果再次往里面存东西只是说覆盖了之前存储的东
//西,所以说如果硬盘上的东西如果不小心删除了,只要再不往里面存东西,是可以有
//办法恢复之前存储的东西的,当然硬盘存储可能根本不是队列,但原理应该差不多。
p->EnQueue(60);
cout << "重新插入元素后遍历队列:" << endl;
p->QueueTraverse();

delete [4]p;							//释放实例化队列的空间
p=NULL;
system("pause");
return 0;
}

这个操作让我想到删除硬盘上的东西是不是只是移动了指针,而没有真正的删除已存储的东西。如果再次往里面存东西只是说覆盖了之前存储的东西,所以说如果硬盘上的东西如果不小心删除了,只要再不往里面存东西,是可以有办法恢复之前存储的东西的,当然硬盘存储可能根本不是队列,但原理应该差不多。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: