大根堆的含义是:最大的先出队,所以是从小到大排序。在自定义结构体中,要定义小于号。
如何理解,大根堆指数列从左到右按照从小到大的顺序排列,这样,在右侧出队时,就是最大的。
系统默认是大根堆,完整的写法是:priority_queue<int,vector<int>,less<int> > q
,可以省略为:priority_queue<int> q
当在结构体中时,要定义一下小于号。告诉结构体如何按照从小到大排序。
#include <cstdio>
#include <queue>
using namespace std;
struct node{
int x,y;
friend bool operator<(const node& a,const node& b){
return a.x<b.x || (a.x==b.x&&a.y<b.y);
}
node(){}
node(int a,int b):x(a),y(b){}
};
int main(){
priority_queue<node> q;
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int t1,t2;
scanf("%d%d",&t1,&t2);
q.push(node(t1,t2));
}
for(int i=0;i<n;i++){
printf("%d ",q.top().x);
q.pop();
}
printf("\n");
return 0;
}
小根堆的含义:最小的先出队,所以要从左到右按照从大到小的顺序排。要定义大于号。
定义小根队:priority_queue<int,vector<int>,greater<int> > q
#include <cstdio>
#include <queue>
using namespace std;
struct node{
int x,y;
friend bool operator>(const node& a,const node& b){//改成大于号
return a.x>b.x || (a.x==b.x&&a.y>b.y);
}
node(){}
node(int a,int b):x(a),y(b){}
};
int main(){
priority_queue<node,vector<node>,greater<node> > q;//添加被省略的参数
int n;
scanf("%d",&n);
for(int i=0;i<n;i++){
int t1,t2;
scanf("%d%d",&t1,&t2);
q.push(node(t1,t2));
}
for(int i=0;i<n;i++){
printf("%d ",q.top().x);
q.pop();
}
printf("\n");
return 0;
}
友元friend
在结构体内,结构体的函数定义成友元函数,是为了在结构体外调用函数时,可以省略类名,因为友元函数设立目的就是,不是类函数,但是可以调用类的私有变量。
如何理解:
采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分(注意友元函数不是类的一部分),但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数外,还有友元类,两者统称为友元。友元的作用是提高了程序的运行效率(即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
#include<iostream>
using namespace std;
struct node{
string name;
friend void display(const node& a);//函数体可以写在这里,也可以写在外面,友元函数不属于类node
};
void display(const node& a){
cout<<a.name<<endl;
}
int main(){
node w;
w.name="hello";
display(w);
return 0;
}
其他
有些人把比较函数和自定义运算符结合起来写,在定义大于号的函数,返回小于号,这样写扭曲了人性,太容易出错了。
写得好xd