队列与优先队列详解

今天给大家(自己)讲讲队列和优先队列吧~
首先讲讲什么是队列,一讲到队列就会想到栈(stack),栈是一种先进后出(FILO)的数据结构, 而队列,就是一种先进先出(FIFO)的数据结构。先进先出就不用我讲了吧~
这里的话很多函数的实现原理大家感兴趣可以自己多多去了解,我们主要讲应用。

  1. 头文件
#include 
using namespace std;

所有的队列都是这个库噢。

  1. 队列的声明
queue<数据类型> 名称
//例如
queue<int> q;
queue<vector<int>> q;
queue<node> q; //这里的数据类型是一个结构
  1. .一些队列的操作
q.push(item);//入队操作,并且是从队尾进入
q.top();//返回队首元素 q.front()同样也可以
q.pop();//删除队首元素,注意与上面的区别,且经常与上面的操作同时使用
q.back()//返回队尾元素
q.size()//返回元素的个数
q.empty()//bool变量,如果队列为空则返回true

注意队列只允许在队首出元素,队尾进元素。

  1. 接下来手写一个队列吧哈哈

应该有很多朋友学的是C语言实现数据结构,并不会STL,那我们就来写一个队列吧,但其实吧,手写一个队列是有很大好处的,就跟栈一样,使用STL很容易溢出,至于为什么,大家看完后有兴趣可以去了解了解噢~手写能解决这个问题噢。

class queue {
private:
	int data[maxc];//maxc 随便你设多大~
	int head, tail;//head指向队首, tail指向队尾
public:
	void Init_queue(queue q);
	bool empty(queue q);
	bool push(queue q);//这里还加了判断是否队列已经满了
	void pop(queue q); 
};

void queue::Init_queue(queue q) {
	q.head = q.tail = -1;
}

bool queue::empty(queue q) {
	return q.head == q.tail;//head++是出队,tail++是入队
}

bool queue::push(queue q, int e) {
	if(q.tail == maxc - 1)
		return false;
	q.tail++;
	q.data[tail] = e;
	return true;
}

void queue::pop(queue q) {
	q.data[head++] = 0;
}

博主还不够强,没有力量,要是有写的不对的地方还望指正。

  1. 总结队列

队列的好处:可以很快做到先进先出,对于模拟一些现实的情况很有帮助,能在O(1)的复杂度内去添加和删除元素。

队列的坏处:不知道大家发现了没有,队列的入队和出队操作都是把下标++,这样就会造成前面使用过的内存空间,一旦元素被删除,那么该空间将永远不再被使用!这是对空间极大的浪费!于是我们有了循环队列!关于循环队列,很多的数据结构的书上都有详细的图解,我也就不多赘述了~

其实用循环队列也有不足的地方:循环队列要事先申请内存空间,整个过程都不能释放,而且要有固定的长度,如果长度无法事先估计,这种方式就显得不够灵活;所以就引入了链式储存队列,其实就是线性表的单链表,只是它只能队尾进,队首出。并且规定头指针指向链队列的头节点,队尾指针指向终端节点, 当队列为空时,head、tail都指向头结点。

  1. 优先队列

优先队列具有根据一定的优先级顺序自动排序的功能。
优先队列,顾名思义,就是让优先级高的先出列,它是队列和排序的完美结合!不仅可以存储数据,还可以根据一定的优先顺序进行排序,对每一次push()和pop()操作,优先队列都会自己动态调整,把优先级高的元素放在前面,维护了一个全局的有序性!
在STL中,优先队列是运用二叉堆来实现的,每次push()和pop()操作,复杂度都是O(logn)。而运用优先队列的排序的复杂度是O(nlogn),还是很优的。

  1. 优先队列的声明
priority_queue<数据类型> q;

然后讲讲优先队列的模板:

priority_queue<int, vector<int>, less<int>> q;
//第一个int:优先队列里存储的数据类型
//第二个vector:优先队列的储存工具是向量
//第三个less:指的是该队列是降序排列(优先队列默认排序就是降序 所以可以不写噢)
priority_queue<int, vector<int>, greater<int>> q;
//有降序就有升序
//有降序升序就有自定义顺序!
  1. 优先队列自定义优先级的方法

它是重载运算符‘<’实现的,那就给大家看看默认的优先级是如何实现的吧:

struct node {
	int x;
	bool operator < (const node& n) const {
		return n.x > x;
	}
}

不知道大家看到这里会不会想起sort函数里的compare函数,大家看看compare函数会咋写来实现这个功能

bool cmp(node n1, node n2) {
	return n1.x > n2.x;
}

大家可以看到,在compare函数里,我们默认写在前面的n1是排在前面的,而n2就排在n1的后面。那么我们类比一下,重载运算符函数里的n是默认排在前面的,而结构体里的则是默认排在n后面的,应该能听懂吧。。。

附上一道优先队列入门题~
1873优先队列入门题

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