文章目录
一、queue
queue为队列,具有先进先出的特性。使用queue,需要添加#include< queue >和using namespace std;
1、queue的定义:
queue<typename> name;//typename可以是任意基本数据类型或容器
queue元素的访问:
由于queue本身就是一种先进先出的限制性数据结构,所以STL只能够提供front()来访问队首元素,用back()来访问队尾元素
#include<queue>
#include<stdio.h>
using namespace std;
int main(){
queue<int> q;
for(int i = 1 ; i <= 5 ; i++)
q.push(i);
printf("%d",q.front());//1
return 0;
}
3、push()
push(x):将x入队,插入到队尾的位置
4、pop()
令队首元素出队
#include<queue>
#include<stdio.h>
using namespace std;
int main(){
queue<int> q;
for(int i = 1 ; i <= 5 ; i++)
q.push(i);
for(int i = 1 ; i <= 3 ; i++)
q.pop();
printf("%d",q.front());//4
return 0;
}
5、empty()
检测队列是否为空,如果是则返回true,不是则返回false
6、size()
返回队列中元素的个数
注意:在使用front()和pop()函数之前,必须使用empty()函数判断队列是否为空,否则可能出现错误
二、priority_queue
优先队列,底层是用堆来实现的,在优先队列中,队首元素一定是当前队列中优先级最高的那一个。使用的时候要添加#include< queue >以及using namespace std;
1、priority_queue的定义:
priority_queue<typename> name;
2、priority_queue容器内元素的访问:
与queue不同的是,优先队列没有front()和back()函数,只能够通过top()函数来访问队首元素
#include<queue>
#include<stdio.h>
using namespace std;
int main(){
priority_queue<int> q;
q.push(3);
q.push(4);
q.push(1);
printf("%d",q.top());//4
return 0;
}
3、push():
push(x):令x入队
4、top():
可以获得队首元素,实现容器内元素的访问
5、pop():
令队首元素出队
6、empty():
检测队列是否为空,若为空则返回true,否则返回false
7、size()
返回优先队列中元素的个数
8、元素优先级设置
(1)基本数据类型的优先级设置
以int类型为例,下面两种定义是等价的:
priority_queue<int> q;
priority_queue<int,vector<int>,less<int> > q;
第二种方式中vector< int >是来承载底层数据结构堆得容器,而less< int >则是对第一个参数的比较类,less< int >表示数字大的优先级越大,greater< int >表示数字小的优先级越大
#include<queue>
#include<stdio.h>
using namespace std;
int main(){
priority_queue<int,vector<int>,greater<int> > q;//数字小的优先级越大
q.push(3);
q.push(4);
q.push(1);
printf("%d",q.top());//1
return 0;
}
(2)结构体优先级设置
如用水果的名称和价格建立一个结构体,现在希望对水果价格高的优先极高,就需要重载“<”小于号,重载大于号会编译错误。
struct fruit{
string name;
int price;
friend bool operator < (fruit f1 , fruit f2){
return f1.price < f2.price;
}
};
注意:优先队列中的这个函数与sort中的cmp函数的效果是相反的,设置f1.price<f2.price是从小到大排列, 但是在优先队列中的效果是价格高的优先级高
示例:想以价格低的水果优先级高
#include<queue>
#include<string>
#include<iostream>
using namespace std;
struct fruit{
string name;
int price;
friend bool operator < (fruit f1 , fruit f2){
return f1.price > f2.price;
}
}f1,f2,f3;
int main(){
priority_queue<fruit> q;
f1.name = "桃子";
f1.price = 3;
f2.name = "梨子";
f2.price = 4;
f3.name = "苹果";
f3.price = 1;
q.push(f1);
q.push(f2);
q.push(f3);
cout<<q.top().name<<" "<<q.top().price<<endl;
return 0;
}
**常见用途:**可以解决一些贪心问题,也可以对迪杰斯特拉算法进行优化
三、stack
栈:后进先出的容器。想要使用栈,必须添加#include< stack >并加上using namespace std;
1、stack的定义:
stack<typename> name;
2、元素的访问:
stack中只能通过top()来访问栈顶元素
3、push():
push(x):将x入栈
4、pop()
pop()用以弹出栈顶元素
#include<stdio.h>
#include<stack>
using namespace std;
int main(){
stack<int> s;
for(int i = 1 ; i <= 5 ; i++)
s.push(i);
for(int i = 1 ; i <=3 ; i++)
s.pop();
printf("%d",s.top());//2
return 0;
}
5、empty():
检测stack是否为空,如果为空返回true,不为空则返回false
6、size():
返回stack内的元素的个数
四、pair
当想要将两个元素绑在一起作为一个合成元素、又不想定义结构体时,可以使用pair。也就是说,pair实际上可以看做一个内部有两个元素的结构体。想使用pair,要添加#include< utility >以及using namespace std。
1、pair的定义:
pair<typename1,typename2> name;
如:
pair<string,int> p;
也可以定义的时候进行初始化:
pair<string,int> p("haha",5);
2、元素的访问:
pair中只有两个元素,分别为first和second
#include<utility>
#include<iostream>
#include<string>
using namespace std;
int main(){
pair<string,int> p;
p.first="haha";
p.second=5;
cout<<p.first<<" "<<p.second<<endl;
p = make_pair("xixi",55);
cout<<p.first<<" "<<p.second<<endl;
p = pair<string,int>("heihie",555);
cout<<p.first<<" "<<p.second<<endl;
return 0;
}
3、比较:
两个pair类型可以通过==、!=、<、<=、>、>=比较大小,规则是先以first的大小作为标准,只有当first相等时再去判别second的大小
常见用途:
- 用来代替二元结构体及其构造函数
- 作为map的键值对来进行插入
#include<utility>
#include<iostream>
#include<string>
#include<map>
using namespace std;
int main(){
map<string,int> mp;
mp.insert(make_pair("heihei",5));
mp.insert(pair<string,int>("haha",10));
for(map<string,int>::iterator it = mp.begin();it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
五、algorithm头文件下的常用函数
1、max()、min()、abs():
max(x,y)、min(x,y)返回x、y中的最大值和最小值。且参数必须是两个,如果有三个参数,可以使用max(x,max(y,z))的写法。
abs(x)返回x的绝对值。x必须是整数,如果是浮点数请用math头文件下的fabs
2、swap():
swap(x,y)用来交换x、y的值
3、reverse():
reverse(it,it2)可以将数组指针在[it,it2)之间的元素或容器的迭代器在[it,it2)范围内的元素进行反转
#include<stdio.h>
#include<string>
#include<algorithm>
using namespace std;
int main(){
string str = "abcdefghi";
reverse(str.begin()+2,str.begin()+6);
for(int i = 0 ; i < str.length() ; i++)
printf("%c",str[i]);//abfedcghi
return 0;
}
4、next_permutation():
给出一个序列在全排列中的下一个序列。
例如:当n=3时的全排列
123
132
213
231
312
321
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int a[10]={1,2,3};
do{
printf("%d%d%d\n",a[0],a[1],a[2]);
}while(next_permutation(a,a+3));
return 0;
}
在到达全排列的最后一个时next_permutation会返回false,这样会方便退出循环
5、fill():
可以将数组或容器中的某一段区间赋值为某个相同的值,与memset不同,这里的赋值可以是数组类型对应范围内的任何值
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int a[5]={1,2,3,4,5};
fill(a,a+5,233);
for(int i = 0 ; i < 5 ; i++)
printf("%d ",a[i]);
return 0;
}
6、sort():
是用来排序的函数:
sort(首元素地址,尾元素地址的下一个地址,比较函数)
比较函数可以根据需要填写,如果不写,默认对前面给出的区间进行递增排序
例如:对于char型数组从大到小排序(按字典序)
#include<stdio.h>
#include<algorithm>
using namespace std;
bool cmp(char a , char b){
return a>b;
}
int main(){
char a[] = {'T','W','A','K'};
sort(a,a+4,cmp);;
for(int i = 0 ; i < 4 ; i++)
printf("%c",a[i]);//WTKA
return 0;
}
如:对于结构体的排序定义,x不等时按照x从大到小排序,x相等时按照y从小到大排序
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node{
int x,y;
}ssd[10];
bool cmp(node a , node b){
if(a.x != b.x)
return a.x > b.x;
else
return a.y < b.y;
}
int main(){
ssd[0].x = 2;
ssd[0].y = 2;
ssd[1].x = 1;
ssd[1].y = 3;
ssd[2].x = 2;
ssd[2].y = 1;
sort(ssd,ssd+3,cmp);
for(int i = 0 ; i < 3 ; i++)
printf("%d %d\n",ssd[i].x,ssd[i].y);
return 0;
}
// 2 1
// 2 2
// 1 3
容器的排序:在STL中,只有vector、string、deque时可以使用sort的,因为set和map这种容器本身就有序
#include<stdio.h>
#include<vector>
#include<algorithm>
using namespace std;
bool cmp(int a , int b){
return a>b;
}
int main(){
vector<int> vi;
vi.push_back(3);
vi.push_back(1);
vi.push_back(2);
sort(vi.begin(),vi.end(),cmp);
for(int i = 0 ; i < 3 ; i++)
printf("%d ",vi[i]);
return 0;
}
7、lower_bound()、upper_bound()
需要用在一个有序数组或者容器中。
lower_bound(first,last,val)寻找在数组或容器的[first,last)范围内第一个值大于等于val的元素的位置,如果是数组则返回该位置的指针,如果是容器,则返回该位置的迭代器
upper_bound(first,last,val)寻找在数组或容器的[first,last)范围内第一个值大于val的元素的位置,如果是数组则返回该位置的指针,如果是容器,则返回该位置的迭代器
如果没有寻找到,则返回可以插入该元素的位置的指针或者迭代器
#include<stdio.h>
#include<algorithm>
using namespace std;
int main(){
int a[10] = {1,2,2,3,3,3,5,5,5,5};
//寻找-1
int* lowerPos = lower_bound(a,a+10,-1);
int* upperPos = upper_bound(a,a+10,-1);
printf("%d,%d\n",lowerPos-a,upperPos-a);//0,0
//寻找3
lowerPos = lower_bound(a,a+10,3);
upperPos = upper_bound(a,a+10,3);
printf("%d,%d\n",lowerPos-a,upperPos-a);//3,6
return 0
}