【STL】一、STL中的数据结构(不断更新)

目录

  • 总:对比表
  • 一、priority_queue(优先队列,最大堆)
    • 1. 模板参数
    • 2. 简述
    • 3. 成员函数
    • 4. 如何实现最小堆?
    • 5. 如何修改function参数?
    • 5. 注
  • 二、deque(双向队列)
    • 1. 模板参数
    • 2. 简述
    • 3. 成员函数
  • 三、set(不重复集合)
    • 1. 模板参数
    • 2. 简述
    • 3. 成员函数


注:本博文主要是为了记录STL中各数据结构的三个成员函数(压入、弹出、顶数据)的函数名,但像判空.empty()、长度.size()这些成员,在STL的所有数据结构中都使用了同样的名字,所以不再赘述。


总:对比表

数据结构 在STL中的名字 删除
最大堆 priority_queue< Type > Q.push() Q.pop() Q.top() 只有Q.pop(),只能删除堆顶元素 虽然是一个queue,但队列头的返回方式不是Q.front(),而是Q.top(),取最大堆的“堆顶”之意。
双向链表 deque< Type > Q.push_front()、Q.push_back() Q.pop_front()、Q.pop_back() Q.front()、Q.back() Q.erase(iter) 由于其是双向链表,因此一切操作都有前(front)、后(back)两种。
不重复结合 set< Type > st.insert() 无(只有同其他类型一样的删除erase) 无(只有同其他类型一样的头迭代器st.begin()和尾迭代器st.end()) ①st.erase(val);//删除set中值为val的元素 ②st.erase(iter);//删除迭代器iter指向的元素 ③st.erase(iter1, iter2);//删除迭代器itera核iter2范围内的所有元素(不包含iter2) set比较特殊,解释请看博客后文第三部分

一、priority_queue(优先队列,最大堆)

参考: CSDN博主【WhiteJunior】的文章C++中priority_queue理解与使用

priority_queue直译名为优先队列,直接作用是最大堆

作为队列的一个延伸,优先队列包含在头文件 < queue > 中。

1. 模板参数

priority_queue< type, container, function >

后面两个参数可以省略。

其中:

type:数据类型;
container:实现优先队列的底层容器;
function:元素之间的比较方式;

对于container,要求必须是数组形式实现的容器,例如vector、deque,而不能使list。

在STL中,默认情况下(不加后面两个参数)是以vector为容器,以 operator <(小于号,则队顶为最大值) 为比较方式,所以在只使用第一个参数时,优先队列默认是一个最大堆,每次输出的堆顶元素是此时堆中的最大元素。

2. 简述

优先队列时一种比较重要的数据结构,它是有二项队列编写而成的,可以以O(log n) 的效率查找一个队列中的最大值或者最小值,其中是最大值还是最小值是根据创建的优先队列的性质、也就是由 人为设定的比较函数(上述第三个参数function) 来决定的。

3. 成员函数

Q.push() Q.pop() Q.top()

4. 如何实现最小堆?

方法一: 把待输入的元素全都取相反数,如{1, -2, 3} 变为{-1, 2, -3}这样再存到priority_queue中,它就变成了原数组的一个最小堆,只是数字变成了原数组的相反数。

方法二: 自定义如1中所述模板参数的第三个参数,把比较函数设为大于比较,即函数作用与**opertor >**相同,则变成了最小堆。

5. 如何修改function参数?

示例1:

priority_queue<int, vector<int>, greater<int>> q;

示例2:

//重载操作符 < 或 >
 1 #include <iostream>
 2 #include <queue> 
 3 using namespace std;
 4 struct Node{
 5     int x, y;
 6     Node(int a=0, int b=0):
 7         x(a),y(b){}
 8 };
 9 bool operator<(Node a, Node b){//返回true时,说明a的优先级低于b
10     //x值较大的Node优先级低(x小的Node排在队前)
11     //x相等时,y大的优先级低(y小的Node排在队前)
12     if( a.x== b.x ) return a.y> b.y;
13     return a.x> b.x; 
14 }
15 int main(){
16     priority_queue<Node> q;
17     for( int i= 0; i< 10; ++i )
18     q.push( Node( rand(), rand() ) );
19     while( !q.empty() ){
20         cout << q.top().x << ' ' << q.top().y << endl;
21         q.pop();
22     }
23     return 0;
24 }

示例3:

//写一个新的结构体
 1 #include <iostream>
 2 #include <queue>
 3 using namespace std;
 4 struct Node{
 5     int x, y;
 6     Node( int a= 0, int b= 0 ):
 7         x(a), y(b) {}
 8 };
 9 struct cmp{
10     bool operator() ( Node a, Node b ){//默认是less函数
11         //返回true时,a的优先级低于b的优先级(a排在b的后面)
12         if( a.x== b.x ) return a.y> b.y;      
13         return a.x> b.x; }
14 };
15 int main(){
16     priority_queue<Node, vector<Node>, cmp> q;
17     for( int i= 0; i< 10; ++i )
18     q.push( Node( rand(), rand() ) );
19     while( !q.empty() ){
20         cout << q.top().x << ' ' << q.top().y << endl;
21         q.pop();
22     }
23     return 0;
24 }

示例4:(leetcode 3 / 14 周赛:最大平均通过率)

//在以下程序中,priority_queue保存的是tuple类型,则它先按tuple的第一个元素排序;若第一个元素相等,再按第二个元素排序;若第二个也相等,再按第三个元素排序。
class Solution {
public:
    double maxAverageRatio(vector<vector<int>>& classes, int extraStudents) {
        priority_queue<tuple<double, int, int>> q;

        auto diff = [](int x, int y) -> double {
            return (double)(x + 1) / (y + 1) - (double)x / y;
        };

        double ans = 0;

        int length = classes.size();
        for(int i = 0; i < length; i++)
        {
            ans += (double)classes[i][0] / classes[i][1];
            q.emplace(diff(classes[i][0], classes[i][1]), classes[i][0], classes[i][1]);
        }

        for(int i = 0; i < extraStudents; i++)
        {
            auto[d, x, y] = q.top();
            q.pop();
            ans += d;
            q.emplace(diff(x+1, y+1), x+1, y+1);
        }

        return ans/length;
    }
};

5. 注

priority_queue不能用下标取值,即没有priority_queue[i]操作。


二、deque(双向队列)

参考: CSDN博主【千寻~】的文章deque用法详解

deque直译名为双向队列,包含在头文件 < deque > 中。

1. 模板参数

deque< Type >

2. 简述

deque是一个线性双向队列,既可以从头插入、也可以从尾插入;同样,既可以从头删除,也可以从尾删除。当然,还包含对任意位置的插入删除操作。

3. 成员函数

由于其是双向链表,因此一切操作都有前(front)、后(back)两种。

Q.push_front() Q.pop_front() Q.front()
Q.push_back() Q.pop_back() Q.back()

三、set(不重复集合)

set不重复集合,包含在头文件 < set > 中。

1. 模板参数

set< Type >

2. 简述

set不重复集合,即如果有两个一样的元素想要存入set,则set只会保留其中一个;且set会自动为其保存的元素进行排序

3. 成员函数

set比较特殊,并push为插入,而是以insert为插入,因为set会自动排序,所以不一定后插入的元素就保存在后边,所以不能取 push 之意,而要取 insert 之意。(push有往后插入的意思,而insert是往后或往任意位置插入均可)

由于set会自动排序,那么我们也就难以确定它的最后一个元素是什么,所以set类型没有pop,只有erase作删除用。

st.insert() 无(只有同其他类型一样的删除erase) 无(只有同其他类型一样的头迭代器st.begin()和尾迭代器st.end())

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