1.队列
队列作为一种先进先出的数据结构,只允许在队尾插入元素,队首删除元素,是一种特殊的线性表。队列可以分为顺序队列和循环队列,这里讲的都是顺序队列。队首指针front指向队首元素的前一个位置,队尾指针rear指向队尾元素。用数组实现队列时首尾指针都是int型变量,用链表实现队列时是int*类型的指针。
2.队列的基本操作
以int数组为例,队列中没有元素时front和rear的值都为-1
(1)获取队列内元素的个数
int size(){
return rear-front;
}
(2)队列为空
bool empty(){
if(rear==front)
return true;
return false;
}
(3)入队
void push(int x){
rear++;
q[rear]=x;
}
(4)出队
void pop(){
front++;
}
(5)获取队首元素
int get_front(){
return q[front+1];
}
(6)获取队尾元素
int get_rear(){
return q[rear];
}
注意:在出队、获取队首尾元素这几个操作前都要先判断队列是否为空。
(7)清空
void clear(){
front=rear=-1;
}
3.stl中的队列
(1)头文件
#include <queue>
using namespace std;
(2)定义
typename可以是任意基本数据类型或容器。
queue<typename> q;
(3)常用函数
1.push()
push(x)将元素x入队
2.pop()
使队首元素出队
3.front()
返回队首元素
4.back()
返回队尾元素
5.empty()
判断队列是否为空,空返回true,否则返回false
6.size()
返回队列内元素的个数
简单实例:
#include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;
int main(){
queue<int> q;
for(int i=1;i<=5;i++)
q.push(i);
printf("%d %d\n",q.front(),q.back()); //1 5
while(!q.empty()){
q.pop();
}
printf("%d\n",q.size()); //0
return 0;
}
4.优先队列
优先队列(priority_queue)不同于普通队列的是队列中的元素被赋予了优先级,队首元素一定是队列中优先级最高的。优先队列本质是用堆是实现的,每次入队时可以随时调整队列结构使优先级最高的元素排在队首。
(1)头文件
和普通队列一样
#include <queue>
using namespace std;
(2)定义
priority_queue<typename> q;
(3)常用函数
除了front()和back()函数优先队列中没有,其余函数都和普通队列一样,优先队列中使用top()函数获得队首元素。
(4)元素优先级的设置
1.基本数据类型的优先级设置
以int数据类型为例,定义如下优先队列:
priority_queue<int,vector<int>,less<int> > q;
其中第一个参数int表示队列的数据类型,第二个参数vector是底层的堆的容器(堆的容器类型要跟队列类型一致),第三个参数是对第一个参数的比较类,less表示值越大的优先级越大,greater表示值越小的优先级越大。
简单实例:
#include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;
int main(){
priority_queue<int,vector<int>,less<int> > q;
for(int i=1;i<=5;i++)
q.push(i);
printf("%d\n",q.top()); //5
for(int i=0;i<3;i++)
q.pop();
printf("%d\n",q.top()); //2
return 0;
}
2.结构体的优先级设置
定义如下结构体:
struct node{
int x,y;
};
如果希望将x值越大的设为优先级越高,可以通过重载<
struct node{
int x,y;
friend bool operator < (node n1,node n2){
return n1.x<n2.x;
}
}
x值越小优先级越高也是重载<(重载>会编译错误,记住就行)
struct node{
int x,y;
friend bool operator < (node n1,node n2){
return n1.x>n2.x;
}
};
简单实例:
#include <stdio.h>
#include <iostream>
#include <queue>
using namespace std;
struct node{
int x,y;
friend bool operator < (node n1,node n2){
return n1.x>n2.x; //x值越小优先级越大
}
};
int main(){
priority_queue<node> q;
node n1,n2;
n1.x=1;
n1.y=2;
n2.x=2;
n2.y=1;
q.push(n2);
q.push(n1); //队首元素为n1
printf("%d %d\n",q.top().x,q.top().y); //1 2
return 0;
}
优先队列中的重载小于号函数和sort中的cmp函数比较类似,都是返回true或false,不过两者的效果是相反的。在sort中n1.x<n2.x表示的是按照x的值升序排序,而在优先队列中n1.x<n2.x表示把x值最大的元素放在队首,也就是降序排序。这是由于优先队列默认的规则就是把值大的元素放在队首。
如果结构体内数据较大(字符串或数组),建议使用引用提高效率:
friend bool operator < (const node &n1,const node &n2){
return n1.x<n2.x;
}