(循环)队列(Queue)简单实现

前言

写dp写晕了。。。赶紧来个队列休息一下。

队列是模仿现实生活当中的“排队”的。当然,电脑当中的队列可是比现实生活当中的规矩多了:没人插队,先排队进来的永远先出队。示意图如下:
(循环)队列(Queue)简单实现_第1张图片
计算机当中是怎么实现的呢?
一般定义一个head指针,一个tail指针,head指向队列的头,tail指向队列的尾,每次插入一个元素,那么就把tail指针往后一个,每次弹出一个元素,就会把head指针往后移一位。如图
(循环)队列(Queue)简单实现_第2张图片
“删除”在计算机当中很多时候不意味着真的将其删除了,只是将指针指向别处,导致你无法访问该元素,同时将该地址标记为“可复写”。所以该数据还是存在于这个队列当中的,处于等待复写的状态。

但是这样会引来一个问题:假设我们的队列只有两个空间,当tail指向第三个空间时就代表队列满了,那么此时弹出张三,其实空间又增加了一个,但是从tail的判断上却发现已经满了,而不能入队。

这个问题的解决方案:可以多定义两个变量:一个指针end指向该点,一个msize表示当前的元素数量。当tail和head指针达到end的时候,让他们直接回到整个分配的空间首地址去(注意head不是队列的首地址,只是队列第一个元素的地址),而msize则专门用来判断是否真的队列已经满溢了。

注意,此时可能会出现以下情况:
(循环)队列(Queue)简单实现_第3张图片
此时tail在head的前面,所以在扩容时候不能使用realloc函数,否则序列可能会出现错乱。

这样就完成了一个循环队列。

队列在BFS广度优先搜索 (breadth-first search)用处非常广泛。是一个重要的数据结构。

注意事项

队列也应当有自动扩容的功能,而不需要让人动手去扩容。比较重要的函数有:

  1. push():从队尾加入一个新元素
  2. pop():从队首弹出一个元素
  3. front():取出第一个元素的值

老样子,还是实现最简单的队列,存储int型。

代码

#include
#include
#include
#include
using namespace std;

class Queue {
   
private:
	int* mdata, * head, * tail, * end, msize, mcapacity;

	int expand() {
   
		int extra_size = mcapacity;
		int* p = nullptr;
		while (extra_size) {
   
			p = new int[mcapacity + extra_size]();
			if (

你可能感兴趣的:(队列,链表,数据结构,指针)