1 普通队列与环形队列
队列的特点:先入先出(FIFO)
例子: 火车站买票时,队头队尾。售票员从头开始卖票,先到的人先买到票就可以离开。
分类:普通队列与环形队列
1.1 普通队列
普通队列的添加元素较为简单,直接队列尾后移;
普通队列的删除元素分为两种:
(1)队列头位置不变,后面所有元素前移一位(浪费时间)
(2)队列头直接后移一位(浪费内存)
1.2 环形队列
将队列首尾相连,即节省时间,同时避免浪费内存
2 环形队列例程
一个环形队列的实现对于c++必须要有以下数据成员及成员函数:
创建队列的构造函数(传入队列容量)
销毁队列的析构函数
清空队列
判断队列是否为空
新元素入队
首元素出队
遍历队列
私有数据:队列长度、数组指针、容量
以下是c++实现程序:
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); //首元素出队
void QueueTraverse(); // 遍历队列
private:
int *m_pQueue; //队列数组指针
int m_iQueueLen; //队列元素个数
int m_iQueueCapacity; //队列数组容量
int m_iHead; //数组的下标:队头
int m_iTail; //数组的下标: 队尾
};
#endif /* MyQueue_h */
#include "MyQueue.h"
#include <iostream>
using namespace std;
MyQueue::MyQueue(int queueCapacity)
{
m_iQueueCapacity = queueCapacity;//将用户定义的容积传递给内部变量容积
//初始化队头队尾
m_iHead = 0;
m_iTail = 0;
//队列元素个数初始化
m_iQueueLen = 0;
//分配内存,大小由容量决定
m_pQueue = new int[m_iQueueCapacity]; // 申请内存的失败处理略
ClearQueue();
}
MyQueue::~MyQueue()
{
delete[]m_pQueue;
m_pQueue = NULL;
}
void MyQueue::ClearQueue()
{
// 重置队头队尾
m_iHead = 0;
m_iTail = 0;
// 队列元素个数重置
m_iQueueLen = 0;
}
bool MyQueue::QueueEmpty() const
{
// 长度为0为空,head和tail会移动,此时id为0不一定是空
/*if (m_iQueueLen == 0)
{
return true;
}
else
{
return false;
}*/
return (m_iQueueLen == 0) ? true : false;
}
int MyQueue::QueueLength() const
{
return m_iQueueLen;
}
bool MyQueue::QueueFull() const
{
return (m_iQueueLen == m_iQueueCapacity) ? true : false;
}
// 插入元素
bool MyQueue::EnQueue(int element)
{
//先判断满,容量和长度相同
if (QueueFull())
{
return false;
}
else
{
//插入新元素到当前队尾位置
m_pQueue[m_iTail] = element;
//队尾后移
m_iTail++;
m_iTail = m_iTail % m_iQueueCapacity;//循环
//插入元素改变len
m_iQueueLen++;
return true;
}
}
//这里的element必须是一个引用
bool MyQueue::DeQueue(int &element)
{
if (QueueEmpty())
{
return false;
}
else {
element = m_pQueue[m_iHead];
m_iHead++;
m_iHead = m_iHead % m_iQueueCapacity;
m_iQueueLen--;
return true;
}
}
//使用const函数是为了防止这个函数对数据成员进行改变,这个函数只可以读取数据成员,所以,当不希望函数对数据成员改变时就需要使用从const函数
void MyQueue::QueueTraverse()
{
for (int i=m_iHead;i<m_iHead+m_iQueueLen;i++)
{
cout << m_pQueue[i%m_iQueueCapacity] << endl;
}
}