队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表。
进行插入操作的一端称为队尾,通常称为入队列;进行删除操作的一端称为队头,通常称为出队列。
队列具有先进先出的特性(FIFO)。
循环队列:将头尾相接的顺序存储队列称为循环队列。
【队列满和队列空判断】
1 少用一个存储单元
如果少用一个存储空间,则也队尾指针加1等于对头指针为队列满的判断条件:
(rear+1)%MaxSize==front
队列空的条件仍旧为rear == front
2 设置一个标记
设置标记为flag,初始时置flag = 0;每当入队列操作成功,就置flag=1;每当出队列成功就置
flag=0.此时判断队列空
的条件为:rear == front && flag == 0;判断队列满的条件为rear == front&& flag == 1
3 设置一个计数器
设置计数器count,初始时置count=0,每当入队列操作成功,就是count加1,每当出队列成
功,就使count减1。此时队列空的判断条件为:count==0;队列满的判断条件为count>0 && rear ==
front 或者count == MaxSize
大家可能发现:单是顺序存储,若不是循环队列,算法的时间性能不是很好,循环队列虽然能够解决
问题,但循环队列又面临着数组可能会溢出的问题。
//模拟实现循环队列
template<class T>
class Queue//尾插头删
{
public:
Queue(size_t capacity = 5)
:_capacity(capacity + 3)
, _front(0)
, _rear(0)
, _count(0)
{
_pData = new T[_capacity];
}
void Push(const T& x)
{
//判断满没满
if (_count == _capacity)
{
cout << "队列已满" << endl;
return;
}
_pData[_rear] = x;
_rear = (_rear + 1) % _capacity;//溢出情况下不能直接_rear ++
_count++;
}
void Pop()
{
_front = (_front + 1) % _capacity;
_count--;//也不能直接若_front 在0的位置上,则不能直接count--,
}
T& Front()
{
return _pData[_front];
}
const T& Front()const
{
return _pData[_front];
}
T& Back()
{
return _pData[(_rear - 1) % _capacity];
//此处不能直接返回return _pData[_rear];直接返回是随机值,
//"% _capacity"的原因是防止_rear队列空或满的时候程序崩溃。
}
const T& Back()const
{
return _pData[(_rear - 1)% _capacity];
}
size_t Size()const
{
return _count;
}
bool Empty()const
{
if (0 == _count)
{
return true;
}
else
{
return false;
}
}
~Queue()
{
if (_pData)
{
delete[]_pData;
_pData = NULL;
}
}
private:
T* _pData;
size_t _capacity;
size_t _front;
size_t _rear;
size_t _count;
};
模拟实现循环队列
最新推荐文章于 2022-04-12 11:21:49 发布