目录
1.循环队列
为了解决顺序队列产生的“假溢出”现象,提出的这种头尾相接的队列成为循环队列。
循环队列就是当队尾指针rear到达储存空间的最大值处,让其回退到储存空间的最小值处。
那么问题来了:当队列为空的时候,rear==front,当队列为满的时候的条件是什么呢?
当队列中只剩下一个空余位置的时候,我们可以认为队列已经满了。
这时队空的条件为:front==rear;
队满的条件为:(rear+1)%QueueSize==front,其中QueueSize为队列的长度。
确定了这些边界调节以后,我们来看看代码实现。
# define MAX_SIZE 10
typedef int ElemType;
//队列的定义
struct SQueue
{
ElemType data[MAX_SIZE];
int front;
int rear;
};
//队列的初始化
bool InitQueue(SQueue *queue)
{
queue->front = 0;
queue->rear = 0;
return true;
}
//判断队空
bool Empty(SQueue* queue)
{
return queue->front == queue->rear;
}
//判断队满
bool Full(SQueue* queue)
{
return (queue->rear + 1 + MAX_SIZE) % MAX_SIZE == queue->front;
}
//入队操作
bool Push(SQueue* queue, ElemType e)
{
if (Full(queue))
return false;
queue->data[queue->rear] = e;
queue->rear = (queue->rear + 1 + MAX_SIZE) % MAX_SIZE;
return true;
}
//出队操作
bool Pop(SQueue* queue, ElemType* e)
{
if (Empty(queue))
return false;
*e = queue->data[queue->front];
queue->front = (queue->front + 1 + MAX_SIZE) % MAX_SIZE;
return true;
}
//得到队列元素的个数
int GetLength(SQueue* queue)
{
return (queue->rear - queue->front + MAX_SIZE) % MAX_SIZE;
}
2.链式队列
队列的链式存储结构(链式队列),其实就是线性表的单链表,只不过它只能尾进头出而已。
队空条件为rear==front,由于链表可以无限向后增长,所以不存再队满条件。
链式队列的结构如下所示:
typedef int ElemType;
//节点的定义
typedef struct Node
{
ElemType data;
Node* next;
}*pNode;
//链式队列的定义
typedef struct LinkQueue
{
pNode front, rear;
}*PLinkQueue;
//链式队列的初始化
bool InitQueue(PLinkQueue queue)
{
//申请头节点
pNode header = new Node;
header->next = nullptr;
queue->front = header;
queue->rear = header;
return true;
}
//链式队列的判空
bool Empty(PLinkQueue queue)
{
return queue->front == queue->rear;
}
//链式队列的入队操作
bool Push(PLinkQueue queue, ElemType e)
{
//申请新的节点
pNode newNode = new Node;
newNode->data = e;
newNode->next = nullptr;
//将节点插入队列
queue->rear->next = newNode;
queue->rear = queue->rear->next;
return true;
}
//链式队列的出队操作
bool Pop(PLinkQueue queue, ElemType* e)
{
if (Empty(queue))
return false;
//得到队头结点
pNode temp = queue->front->next;
queue->front->next = queue->front->next->next;
*e = temp->data;
//如果只有一个结点,将对面置空
if (queue->front->next == NULL)
queue->rear = queue->front;
delete temp;
return true;
}
//删除队列
void DelQue(PLinkQueue queue)
{
if (queue->front == NULL)
return;
while (Empty(queue))
{
ElemType e;
Pop(queue, &e);
}
delete queue->front;
queue->front = queue->rear = nullptr;
}
3.优先级队列
优先级队列其实就是有序队列(不出再遵守尾进头出),元素进队列之后要求队列保持有序,出队列的时候按照规则,出最大或者最小。
我们假设优先级队列由小到大排列,并且每次出队列的时候出最小的元素。
# define MAX_SIZE 10
template<typename type> class PriQueue
{
public:
PriQueue(int size = 10) :_size(size), _uSize(0)
{
arr = new type[_size];
}
~PriQueue()
{
delete[] arr;
}
//判断队空
bool Empty()
{
return _uSize==0;
}
//判断队满
bool Full()
{
return _size == _uSize;
}
//入队操作
bool Push(type e)
{
if (Full())
return false;
if (Empty())
{
arr[_uSize++] = e;
}
else
{
int i = _uSize - 1;
for (; i >= 0; --i)
{
if (e < arr[i])
{
arr[i + 1] = arr[i];
}
else
{
break;
}
}
arr[i+1] = e;
++_uSize;
}
return true;
}
//出队操作
bool Pop(type& e)
{
if (Empty())
return false;
e = arr[0];
for (int i = 0; i < _uSize; ++i)
{
arr[i] = arr[i + 1];
}
--_uSize;
return true;
}
void Show()
{
for (int i = 0; i < _uSize ; ++i)
{
cout << arr[i] << ends;
}
}
private:
int _size;//队列长度
int _uSize;//已用长度
type* arr;
};