queue
用途
是一个先进先出的数据结构,与stack正好相反。
使用需添加
基本操作
定义
元素访问
queue的访问比较特殊,queue没有迭代器,每次只能访问队首元素,即使用front()函数。
如果要遍历则需要像这样使用:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16  | #include <iostream>
#include <queue>
using namespace std;
int main()
{
    queue< int > q;
    q.push(1);
    q.push(2);
    q.push(3);
    while( !q.empty() )
    {
        cout << q.front() << " ";
        q.pop();
    }
}
  | 
 
常用函数
| 函数 | 
作用 | 
| q.push() | 
入队 | 
| q.pop() | 
出队 | 
| q.front() | 
返回首元素 | 
| q.back() | 
返回末元素 | 
| q.size() | 
输出现有元素的个数 | 
| q.empty() | 
队列为空返回1,反之返回0 | 
常见使用情况
bfs
假设以邻接表的形式存图。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20  | #include <iostream>
#include <queue>
using namespace std;
const int maxn = 1E5;
bool vis[maxn];
vector<int> G[maxn];
void BFS()
{
    int s;
    queue< int > q;
    q.push(s);
    while( !q.empty() )
    {
        int ft = q.front(); vis[ft] = 1; q.pop();
        for( auto to : G[ft] )
            if( !vis[to] ) q.push(to);
    }
}
  | 
 
最原始的Bellman-Fold
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30  | struct node
{
    int to;
    long long val;
    node( int to = 0, long long val = 0 ) : to(to), val(val) {}
};
vector< node > G[maxn];
long long dis[maxn];
bool inq[maxn];
void SPFA( int s )
{
    memset( inq, 0, sizeof( inq ) );
    for( int i = 1; i < maxn; ++ i) dis[i] = 1E18;
    dis[s] = 0, inq[s] = 1;
    queue< int > q; q.push(s);
    while( !q.empty() )
    {
        int x = q.front(); q.pop();
        inq[x] = 0;
         //这里和堆优化的区别就显现出来了,堆优化版本只会入队一次,而SPFA则不是
        for( auto to : G[x] )
        {
            if( dis[to.to] > dis[x] + to.val )
            {
                dis[to.to] = dis[x] + to.val;
                if( !inq[to.to] ) q.push(to.to), inq[to.to] = 1;
            }
        }
    }
}
  | 
 
时间复杂度
push和pop均为O(1)
priority_queue
用途
保证队首元素优先级最大,相当于大根堆。
使用需添加
常见操作
定义
 | priority_queue< type > name;
  | 
 
常用函数
- 基本与queue相同,只不过priority_queue始终保证队首元素优先级最大,而不是先进先出。
 
- 队首元素需要使用top()而不是front()
 
优先级的设置
同map类似,需要重载 < 号。
但是,排序结果时相反的,因为他是按照优先级来的,所以越大的数,优先级越大,会排在前边。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27  | #include <iostream>
#include <queue>
using namespace std;
struct pet
{
    string species;
    int price;
    bool operator < ( const pet& b ) const
    {
        return price < b.price;
    }
};
int main()
{
    priority_queue< pet > q;
    q.push({"cat",100} );
    q.push({"dog", 50 } );
    q.push({"Tarjan", 10000} );
    while( !q.empty() )
    {
        cout << q.top().species << endl;
        q.pop();
    }
}
  | 
 
输出:
而如果时int等基本类型需要设置越小的数优先级越高,则需要添加
并用如下定义方式:
 | priority_queue< int, vector<int>, greater<int> > q;
  | 
 
如:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18  | #include <iostream>
#include <queue>
#include <functional>
using namespace std;
int main()
{
    priority_queue< int, vector<int>, greater<int> > q;
    q.push(2);
    q.push(50);
    q.push(1);
    while( !q.empty() )
    {
        cout << q.top() << endl;
        q.pop();
    }
}
  | 
 
输出:
常见使用情况
堆优化的Dijkstra和Bellman-Fold
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32  | struct edge
{
    int pos, val;
    edge( int pos = 0, int val = 0 ) : pos(pos), val(val) {}
    bool operator < ( const edge &e ) const
    {
        return val > e.val;
    }
};
vector< edge > G[maxn];
int dis[maxn];
bool vis[maxn];
void Dijkstra( int s )
{
    memset( dis, 0x3f, sizeof( dis ) );
    priority_queue< edge > q;
    dis[s] = 0; q.push({s,dis[s]});
    while( !q.empty() )
    {
        auto tp = q.top( ); q.pop( );
        if ( vis[tp.pos] ) continue;
        inq[tp.pos] = 1;
        for ( auto v : G[tp.pos] )
        {
            if( dis[v.pos] > dis[tp.pos] + v.val )
            {
                dis[v.pos] = dis[tp.pos] + v.val;
                q.push( {v.pos, dis[v.pos]} );
            }
        }
    }
}
  | 
 
一些需要贪心的情况