zoukankan      html  css  js  c++  java
  • priority_queue与multiset

    感觉c++最有用的stl是bitset、堆(优先队列)和平衡树,其他的都可以手打

    这里主要讲一下堆和平衡树的基本用法和区别所在

    priority_queue

    堆/优先队列

    定义:

    priority_queue<类型>
    priority_queue<int> 大根堆
    priority_queue<int,vector<int>,less<int> > 大根堆
    priority_queue<int,vector<int>,greater<int> > 小根堆
    priority_queue<结构体>
    

    基本函数:

    push(x):加入一个元素,可以是数or结构体

    pop():弹出堆顶

    top():堆顶的元素

    size():堆的大小

    empty():是否为空(空即为1)

    关于结构体的比较:

    
    struct type{
    	int x,y;
    	bool friend operator < (type a,type b) {return a.x<b.x;}
        //反正这样写就对了
    };
    

    结构体的赋值可以为{a,b,...}或 名称{a,b,...}

    multiset

    与set的不同在于multiset可以有重复元素,所以一般都用multiset

    定义:

    multiset<类型>
    multiset<int> 从小到大
    multiset<int,less<int> > 从小到大
    multiset<int,greater<int> > 从大到小
    multiset<结构体>
    

    迭代器:

    multiset<定义和对应的set一致> ::iterator
    

    作用是遍历set/特别指向某一个元素

    基本函数:

    insert(x):加入一个元素,可以是数/结构体

    erase(x):

    有两种情况

    ①x是数/结构体

    那么会把所有的x删掉

    ②x是某一个迭代器

    那么只会删掉迭代器对应的元素

    begin():返回关键值最小的元素指针

    (指针x对应的值为*x,如果是结构体则为(*x).a)

    end():返回关键值最大的元素指针的后一位(最大的是--end())

    size()、empty():同优先队列

    lower_bound(x):第一个大于等于x的元素指针

    upper_bound(x):第一个大于x的元素指针

    小于等于=大于 的前一位,小于=大于等于 的前一位

    e.insert(1);e.insert(2);e.insert(3);e.insert(4);e.insert(5);
    cout<<*e.lower_bound(3)<<" "<<*e.upper_bound(3)<<endl;     //>= >
    cout<<*--e.lower_bound(3)<<" "<<*--e.upper_bound(3)<<endl; //<  <=
    //3 4
    //2 3
    

    遍历:
    可以通过迭代器的移动来遍历

    (头为begin(),尾为--end(),最大能走到end())

    
    e.insert(1);e.insert(2);e.insert(3);
    
    I=e.begin();
    while (I!=e.end())
    cout<<*I<<" ",*++I;
    cout<<endl;
    
    //1 2 3
    

    区别

    multiset可以遍历/找前驱后继/删除

    *重点:priority_queue的比较机制和set/sort相反

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <queue>
    #include <set>
    #define fo(a,b,c) for (a=b; a<=c; a++)
    #define fd(a,b,c) for (a=b; a>=c; a--)
    using namespace std;
    
    struct type{
    	int x,y;
    	bool friend operator < (type a,type b) {return a.x<b.x;}
    };
    
    multiset<type> a;
    priority_queue<type> b;
    type c[3];
    
    int main()
    {
    	a.insert({3,3});a.insert({2,2});a.insert({1,1});
    	b.push({1,1});b.push({2,2});b.push({3,3});
    	c[0]={3,3};c[1]={2,2};c[2]={1,1};
    	sort(c,c+3);
    	
    	cout<<(*a.begin()).x<<" "<<b.top().x<<" "<<c[0].x<<endl;
        //1 3 1
    }
    

    可以发现,优先队列得到的结果和multiset/sort刚好相反

    实际上,multiset/sort最终的状态满足a1<a2<a3...<an(<可以是定义的运算)

    而priority_queue应该是当一个元素x满足fa[x]<x时交换,实质上维护的是大根堆

    一种记忆方法:"优先"队列=先大后小

  • 相关阅读:
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』算法设计与分析
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构
    『嗨威说』数据结构的基本概念和术语、算法分析的时间复杂度(深度剖析)
  • 原文地址:https://www.cnblogs.com/gmh77/p/11816070.html
Copyright © 2011-2022 走看看