蓝桥杯基础入门——STL之stack、queue、priority_queue

蓝桥杯入门——STL之stack、queue、priority_queue

在《数据结构》这门课中,我们学习了栈、队列、堆(STL里将堆命名为优先队列priority_queue)等结构,有些同学可能还没学这门课,不过没关系,弄懂基本概念,多使用两次就大概懂在比赛中怎么使用这些结构啦。接下来我们一起看看比赛中需要了解的堆、栈、队列知识吧。

  1. stack(栈)
    (1)简介
    栈是按照后进先出原则存储数据的一种数据结构,数据的读取都在栈的顶部进行,底部不动。进行插入删除的一端称 为栈顶,另一端称为栈底,插入操作称为进栈,删除操作称为退栈。我们可以把栈看做电梯,而乘电梯的人看做栈存储的数据,先进电梯的人总是被堵在里面要等后面进入的人都出去了才能出去,而后面进来的人,总是先出去。
    (2)头文件
#include

(3)定义

//stack<数据类型>变量名
stack<int>s1;
stack<string>s2;

(4)基本操作

stack<int>s;//定义栈
s.push(x);//入栈,将数据x存入栈
s.pop();//出栈,仅删除栈顶元素,不反回该元素
s.top();//访问栈顶元素
s.empty();//判断栈顶元素是否为空,若是则返回true
s.size();//访问栈中元素个数
  1. queue(队列)
    (1)简介
    队列是按照先进先出原则存储数据的一种数据结构,它只允许在表的前端进行删除操作,表的后端进行插入操作,和栈一样,队列是一种操作受限的线性表。进行插入操作的端成为队尾,进行删除操作的端称为队头。队列,就好像我们在食堂窗口排队打菜时的那支队伍,而排队的学生就是队列存储的一个个数据元素,新到来的学生只能从队伍的尾巴插入去排队,而打完菜离开的同学,必然是队伍最前面的同学,只能从队伍的开头离开。
    (2)头文件
#include

(3)定义

//queue<数据类型>变量名
queue<int>q1;
queue<string>q2;

(4)基本操作

queue<int>q;//定义栈
q.push(x);//入队,将数据x接到队列的末端
q.pop();//出队,弹出队列的第一个元素,注意,并不会返回被弹出元素的值
q.front();//访问队首元素,即返回最早被压入队列的元素
q.back();//访问队尾元素,即返回最后被压入队列的元素
q.empty();//判断队列是否为空
q.size();//访问队列中的元素个数
  1. priority_queue(优先队列)
    (1)简介
    优先队列不是按照入队顺序出队,而是按照队列中元素的优先权顺序出队(默认为优先权大的数据先出队列,也可以通过指定算子来指定自己的优先顺序)。定义优先队列时候,有三个参数,数据类型、容器类型和比较算子(作用类似于sort函数中的比较函数cmp)。其中后面两个都可以省略。
    (2)头文件
#include

(3)定义

//priority_queue<数据类型>变量名
priority_queue<int>q1;
priority_queue< pair<int,int> >q2;//注意两个尖括号之间要留空格
priority_queue<int,vector<int>,greater<int> >q3;//定义小的先出队列,调用比较运算符x>y
priority_queue<int,vector<int>,less<int> >q3;//定义大的先出队列,调用比较运算符x

(4)基本操作

priority_queue<int>q;//定义优先队列
q.push(x);//将x存入堆
q.pop();//弹出堆中元素
q.top();//访问优先级最高的元素
q.empty();//判断优先队列(堆)是否为空
q.size();//访问优先队列(堆)中的元素个数

(5)例题
优先队列是一种功能强大的数据结构,它保持了队列的动态有序性,适用于解决不断改变入队操作并求最大或最小值问题。下面以一个例题来说明优先队列在解决实际问题中的应用。
参见south_wind的博客
【问题描述】
在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所耗体力之和。
因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
例如有3种果子,数目依次为1,2,9。可以先将 1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为 12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
【输入文件】
输入文件fruit.in包括两行,第一行是一个整数n(1 <= n <= 10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1 <= ai <= 20000)是第i种果子的数目。
【输出文件】
输出文件fruit.out包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于231。
【样例输入】
3
1 2 9
【样例输出】
15
【数据规模】
对于30%的数据,保证有n <= 1000;
对于50%的数据,保证有n <= 5000;
对于全部的数据,保证有n <= 10000。

题解:每次合并最小两堆,直到只剩下一堆,详细代码如下

#include    
#include    
struct cmp  
{  
    bool operator ()(const int &i,const int &j)  
    {  
        return i>j;  
    }  
};  
using namespace std;  
int main()  
{  
    priority_queue<int,vector<int>,cmp> s;  
    int n;  
    while(cin>>n)  
    {  
        for(int i=0;i<n;i++)  
        {  
            int key;  
            scanf("%d",&key);  
            s.push(key);  
        }  
        int sum=0;  
        while(n>=2)  
        {  
            int a,b;  
            a=s.top();  
            s.pop();  
            b=s.top();  
            s.pop();  
            s.push(a+b);  
            //cout<
            sum+=a+b;  
            n--;  
        }  
        cout<<sum<<endl;  
    }  
    return 0;  
      
}  

优先队列的使用定义

#include
#include//队列头文件
using namespace std;
struct cmp{
  bool operator ()(const 数据类型 变量,数据类型 变量){
       //自定义比较算子,如return i>j;
  }
};
struct node{
  friend bool operator<(node a,node b){
     if(   ) return   ;
     else  return    ;
  }
};
int main(){
  priority_queue<数据类型,vector(数据类型),cmp>s;//法一定义优先队列
  priority_queue<node>que;//法二定义优先队列
  ///其余操作
  for(int i=0;i<n;i++)
    s.push(x)//数据入队
  while(flag){
    a=s.top();//返回即将出队元素值
    s.top();//数据出队列
  }
  return 0;
}

你可能感兴趣的:(蓝桥杯基础入门——STL之stack、queue、priority_queue)