队列
队列:队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。
队列的特点:先进先出。
队列中有两个值,一个是front去记录队头的位置,另一个是rear去记录队尾的位置。
在实际应用时,由于数组队列的缺点是由于一端插入一端删除,当不断从头部删除数据,头部会大量留有空闲内存,无法插入,造成空间流失,这种属于假溢出的情况。但如果将队头指针在每次删除之后往前移动一个位置,这是一个时间复杂度为O(n)的操作。因此,通常将队列设计为循环队列来克服上述问题。
循环队列可以看作是一个环形结构。有一个maxsize表示数组的长度。当队列未满,并且队头已经到达了maxsize的位置,再次插入数据的时候,队头则从0位置开始插入。
在设计的时候,一般要注意以下几点:
(1)队列初始化时,front和rear值都为零。
(2)当队列不为空时,front指向队列的第一个元素,rear指向队列最后一个元素的下一个位置。
(3)当队列为空时,front与rear的值相等,但不一定为零。
循环队列满的时候会满足这个计算公式 : (rear+1)%maxsize=front
计算循环队列长度 : (rear-front+maxsize)%maxsize
以下是使用C++代码实现一个队列:
首先定义一个Queue类
class Queue
{
private:
ElemType *_data;
int _head;
int _tail;
bool IsFull();
bool IsEmpty();
public:
Queue();
Queue(const Queue &src);
Queue& operator= (const Queue& src);
~Queue();
bool Push(ElemType val);
bool Pop();
ElemType GetQue();
void show();
};
判空和判满的实现
bool Queue::IsFull()
{
assert(this != NULL);
if ((_tail + 1) % SIZE == _head)
{
return true;
}
return false;
}
bool Queue::IsEmpty()
{
assert(this != NULL);
if (_head == _tail)
{
return true;
}
return false;
}
出队列、入队列、获得队头的数据的功能实现
bool Queue::Push(ElemType val)
{
assert(this != NULL);
if (IsFull())
{
return false;
}
_data[_tail++] = val;
_tail %= SIZE;
return true;
}
bool Queue::Pop()
{
assert(this != NULL && _data != NULL);
if (IsEmpty())
{
return false;
}
_head++;
_head %= SIZE;
return true;
}
ElemType Queue::GetQue()
{
assert(this != NULL);
if (IsEmpty())
{
return 0;
}
return _data[_head];
}