C++STL

动态数组(vector)

声明

代码

#include<iostream>
#include<vector>

vector <int> a; //一维动态数组
vector <int> b[777];//第一维长777第二位长度动态变化的数组

使用

vector是一个空间能够动态变化的数组,当需要加n个元素时vector会申请2n长度的数组。当当前长度小于等于申请长度的4分之1时,vector会缩小一半的长度。
vector不支持随机插入,但是支持随机访问,元素的删减一般在末尾进行;

操作

插入与删除

a.push_back(x);//把x插入队尾
a.pop_back();//把a尾部的数删除

长度与判空

a.size();//返回当前vector的实际长度,为0时vector为空
vector数组是以a[0]开头的,所以如果用size访问队尾的话要-1;
a.empty();判断当前vector是否为空,如果为空返回1否返回0;

清空

a.clear();清空vector数组;

访问

a.begin();访问vector第一个元素
a.end();访问vector尾部元素
a.front();访问第一个元素 等价于a[0]
a.back();访问最后一个元素等价于a[a.siez() -1]

队列(queue)

声明

代码

#inlcude<iostream>
#inlcude<queue>

queue<int> q;//循环队列
priority_queue<int> q;//大根堆
priority_queue< pair<int, int> > q; //二元队列 q.top().first为第一元, q.top().second为第二元
//比较大小时二元队列以第一元为主关键字,第二元为次关键字
//插入时用q.push(make_pair(x,y));来插入x,y;

循环队列

循环队列有着先进先出的性质,支持访问队头和队尾,但是出队时只能是从队头出队,入队时只能从队尾入队

操作

入队

q.push(x)

出队

q.pop();

访问队头

q.front();

访问队尾

q.back();

优先队列(堆)

使用

插入元素 的方式

q.push();

提取队头

int x = q.top();

弹出队头

q.pop();

大根堆(队头最大)

代码

	std :: priority_queue<int> q;

小根堆(队头最小)

①相反数插入实现

一个大根堆,每次队头都会弹出最大的,那么对于一个int类型的数,如果我们每次把它的相反数入队,出队时也取相反数。
在优先队列中,存进去原本最小的数,就成了最大的数,这样就相当于是一个小根堆了。
代码

std :: priority_queue<int> q;

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		int x;
		scanf("%d", &x); q.push(-x);
	}
	while(!q.empty()){
		int x;
		x = -q.top(); q.pop();
		printf("%d\n",x);
	}
	return 0;
}
②重载运算符实现

重载运算符是比较通用的一种实现小根堆的方法。
建立自定义结构体,重载小于号。
代码

struct cmp{
   bool operator()(const int &a, const int &b){
   			return a>b;
   			}
   		}
   		
   		std :: priority_queue<int, vector<int>, cmp>;

这样的话堆在使用<号时会认为左边的更大,就相当于将 “<” 改成 “>” 使用

在使用优先队列时因为是队列所以不支持随机访问,每次只能访问队头。

小根堆的一个应用(dijkstra的堆优化)

这里只对和堆有关的操作加了注释,要想看dijkstra堆优化更具体解释的话可以到这里
代码

#include<bit/stdc++.h>

#define MAXN 100010
#define INF 0x3f3f3f3f

struct node{
	int y,z,ne;
}e[MAXN];

int lin[MAXN], len = 0;
inline addedg(int x, int y, int z){
	e[++len].y = y; e[len].z = z; e[len].ne = lin[x]; lin[x] = len;
}

int dis[MAXN],vis[MAXN];
priority_queue< pair<int, int > > q;//定义一个二元堆
void dijkstra(){
	memset(dis, INF, sizeof(dis));
	memset(vis, false, sizeof(vis));
	while(!q.empty()){
		int x = q.top().second; q.pop();//取出当前节点,出队
		if(vis[x]) continue;
		vis[x] = true;
		for(int i = lin[x]; i ; i = e[i].ne){
			int y = e[i].y, z = e[i].z;
			if(dis[y] > dis[x] + z){
				dis[y] = dis[x] + z;
				q.push(make_pair(-dis[y], y));//小根堆第一种写法
			}
		}
	}
}

双端队列(deque)

双端队列是一个支持在两端高效插入或删除元素的连续线性储存空间。
双端队列支持队头和队尾插入,同时也支持随机访问。

声明

#inlcude<iostream>
#inlcude<deque>

std :: deque< int > q;

操作

访问队头

q.begin();//类似vector返回的是迭代器
q.front();类似queue

访问队尾

q.end();类似vector返回的是迭代器
q.back();类似queue

推荐用front和back因为begin和end要用迭代器
插入元素

q.push_back(x);插入队尾
q.push_front(x);插入队头

出队

q.pop_front()队头出队
q.pop_back();队尾出队

清空

q.clear();

操作演示代码

#include<bits/stdc++.h>

std :: deque<int> q1;//定义两个双端队列q1,q2
std :: deque<int> q2;
std :: deque<int> :: iterator it; //定义双端队列的两个迭代器
std :: deque<int> :: iterator is;//begin和end返回的是头尾迭代器。

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i){
		int x;
		scanf("%d", &x);
		q1.push_front(x);//从队头插入q1
		q2.push_back(x);//从队尾插入q2
	}

//比较begin,end和front,back
	it = q1.begin(), is = q2.begin(); //读取q1,q1头部迭代器的值
	printf("begin1 = %d begin2 = %d ", *it, *is);//输出,*表示解除引用
	printf("front1 = %d front2 = %d\n", q1.front(), q2.front());//输出队头的值
	it = q1.end(), is = q2.end();//读取q1,q2尾部迭代器的值
	printf("end1 = %d end2 = %d ", *it, *is);
	printf("back1 = %d back2 = %d\n", q1.back(), q2.back());//输出队尾的值

//输出两个双端队列q1,q2
//把长度开两倍后能看见从队头插入的q1会在超出n长度后面两个数会出错
	for(int i = 0; i < (n << 1); ++i){
		printf("q1 = %d q2 = %d\n", q1[i], q2[i]);
	}printf("\n");

	printf("size1 = %d size2 = %d\n", q1.size(), q2.size());//输出长度
	
	q1.clear();//清空队列
	q2.erase(q2.begin() + 1);//删除队头后一个数
	
	printf("size1 = %d size2 = %d\n", q1.size(), q2.size());
	//再次输出长度q1长度为0, q2长度减一
	
	for(int i = 0; i < (n << 1); ++i){//再次输出双端队列,会发现q1数值依旧存在
	//q2原队头后一个数消失,最后一个数变为0
			printf("q1 = %d q2 = %d\n", q1[i], q2[i]);
	}printf("\n");
	return 0;
}
结果演示

在这里插入图片描述

未完待续QwQ

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BIGBIGPPT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值