STL 相关知识点粗略浅过一下(包括迭代器)

一、vector

(1)代码

// vector
// vector 大多数情况下可以代替普通数组(vector 可变长度)
#include <bits/stdc++.h>

using namespace std;

//模拟图的邻接表

int main () {
	vector<int> a[10010]; //建议vector数组开大点
	int n, m; // n 个结点,m条边
	cin >> n >>m;
	for (int i = 0; i < m; ++i) {
		int x, y;
		cin >> x >> y;
		a[x].push_back(y); // 往末尾插入数字
		// a[y].push_back(x);//有向边的话,这一行省略
	}
//	遍历j点的所有邻边
	int j;
	cin >> j;
	for (int i = 0; i < a[j].size(); ++i) {
		printf ("%d ", a[j][i]);
	}
	return 0;
}

(2)测试数据

7 11
1 3
1 4
1 5
2 6
3 7
4 5
5 7
6 3
7 1
7 2
7 3
7

(3)运行结果

在这里插入图片描述

二、栈(stack)

(1)代码

//栈 stack
// i : 入栈
// o : 出栈 
// 数据测试,保证操作有意义(可以不用考虑空) 
#include <bits/stdc++.h>
using namespace std;
stack<int> st;
char op;
int m;//m次操作 
int main () {
	cin >> m;
	int x; // 要插入的数字 
	while (m--) {
		cin >> op;
		if (op == 'i') {
			cin >> x;
			st.push(x); // 压栈 
			printf ("往栈中压入: %d\n", x);
		} else {
			int tp = st.top();	//取栈顶元素 
			st.pop();	// 弹出栈顶元素 
			printf ("栈顶弹出: %d\n", tp);
		}
	} 
	
	printf ("=========================\n");
	int len = st.size();
//	从栈顶开始到栈底
	printf ("从栈顶开始到栈底\n");
	for (int i = 0; i < len; ++i) {
		int tp = st.top();
		printf ("%d ", tp);
		st.pop();
	} 
	printf ("\n");
	
	return 0;
} 

(2)测试数据

6
i 3
i 4
o
i 9
o
i 66 

(3)运行结果

在这里插入图片描述

三、queue队列

(1)代码

//queue队列 --- 从尾进从头出 
//先进先出 
//测试数据

//9
//i 1 
//o 
//i 6
//i 9
//i 10
//i 56
//o
//o
//i 69
#include <bits/stdc++.h>
using namespace std;

queue<int> q;
char op;
int main() {
	int m;	//m次操作 
	int x;	//输入要插入的数 
	cin >> m;
	
	while (m--) {
		cin >> op;
		if (op == 'i') {
			cin >> x;
			q.push(x);
			printf ("从队尾插入 %d\n", x); 
		}else {
			int ft = q.front(); //取队头元素 
			q.pop(); // 从队头弹出
			printf ("从队头弹出 %d\n", ft); 
		}
	} 
	
	printf ("\n打印队列,顺序从头到尾\n");
	
	int len = q.size();
	for (int i = 0; i < len; ++i) {
		int ft = q.front();
		printf ("%d ", ft);
		q.pop();
	} 
	
	
	return 0;
	
}

(2)测试数据

9
i 1 
o 
i 6
i 9
i 10
i 56
o
o
i 69

(3)运行结果

在这里插入图片描述

四、双端队列(deque)

(1)代码

测试数据
front tail
fi:队头插入
fo:队头出去
ti:队尾插入
to:队尾出去 
//9
//fi 6
//fi 9
//fi 12
//fo
//ti 36
//to
//ti 60
//ti 65
//to

//60 6 9 
//双端队列,两头都可以插入或离开
#include <bits/stdc++.h>
using namespace std;

int m;
deque<int> deq; // 声明 
int main() {
	
	string op;
	cin >> m;
	while (m--) {
		cin >> op;
		int x;
		if (op == "fi") {
			cin >> x;
			deq.push_front(x);
			printf ("从双端队列的头部插入:%d\n", x);
		}else if (op == "fo") {
			int fo = deq.front(); 
			deq.pop_front();
			printf ("从双端队列的头部移出:%d\n", fo);
		}else if (op == "ti") {
			cin >> x;
			deq.push_back(x);
			printf ("从双端队列的尾部插入:%d\n", x);
		}else {
			int to = deq.back(); 
			deq.pop_back();
			printf ("从双端队列的尾部移出:%d\n", to);
		}
	}
	
	printf ("\n=============================\n");
	int len = deq.size();
	// 从头到尾输出
	printf ("\n从头到尾输出\n"); 
	for (int i = 0; i < len; i++) {
		int f = deq.front();
		deq.pop_front();
		printf ("%d ", f);
	}
	
	// 从尾到头输出 
	printf ("\n从尾到头输出\n");
	for (int i = 0; i < len; i++) {
		int t = deq.back();
		deq.pop_back();
		printf ("%d ", t);
	}
	return 0;
} 

(2)测试数据

9
fi 6
fi 9
fi 12
fo
ti 36
to
ti 60
ti 65
to

(3)运行结果

在这里插入图片描述

五、优先队列(priority_queue)---- 基础插入弹出操作

(1)代码

// 优先队列 priority_queue 作用和最大(小)堆一样,
//可以O(logn)复杂度插入一个数,弹出一个当前所有数最大(小)值 
// 数据测试:
//i 插入一个数字 x
//o 弹出一个数字 
//10
//i 6
//i 9
//i 39
//o 
//i 36
//o 
//i 99
//o
//o
//i 63 
 
#include <bits/stdc++.h>
using namespace std;
priority_queue<int> pri; // 优先队列
int m;
char op;
int x; // 待操作的数字 
int main() {
	cin >> m;
	while (m--) {
		cin >> op;
		if (op == 'i') {
			cin >> x;
			pri.push(x);
			printf ("往优先队列中插入:%d\n", x);
		}else {
			int maxN = pri.top(); // 堆顶即为最大值(默认情况下) 
			pri.pop();
			printf ("往优先队列中弹出(默认弹出最大值):%d\n", maxN);
		}
	}
	
	printf ("\n===========================\n");
	
	printf ("打印从大到小\n");
	int len = pri.size();
	for (int i = 0; i < len; ++i) {
		printf ("%d ", pri.top());
		pri.pop();
	}
	
	return 0;
} 

(2)测试数据

10
i 6
i 9
i 39
o 
i 36
o 
i 99
o
o
i 63

(3)运行结果

在这里插入图片描述

六、优先队列----弹出最小值,结合结构体

(1)介绍使用

- 如果优先队列要弹出最小值怎么办?
- 第二个参数代表以什么形式(java中还有以链表形式)
- greater<int> 每次弹出最小值
- less<int> 每次弹出最大值
priority_queue<int, vector<int>, greater<int>> q;


- 结构体优先队列的使用:
- 两种方法:
- 1.  重载小于号    bool operator<(const node& a) const{...}
- 2.  重写仿函数    bool operator()(node a, node b){...}
- 第一种方法适用于只需要一种优先队列
- 如果需要多种优先队列,则用第二种方法

(2)实例代码

#include <bits/stdc++.h>
using namespace std;

struct people {
	int age; //年龄 
	string name; //姓名
//	// 重载小于号 方法一 
//	bool operator < (const people &a) const {
//		return this->age < a.age; // 按照年龄从小到大排序 less 在队头的大  top输出的就是年龄较大的 
//	} 
};

// 重写仿函数
struct cmp {
	// 重写仿函数的方法,来改变优先队列 
	bool operator() (people a, people b) {
		return a.age < b.age; // 每次弹出年龄的最大值 其实跟sort的cmp是一样的 
	}	 
};


int main() {
	// 定义people结构体的优先队列 
//	priority_queue<people> a;
	
	priority_queue<people, vector<people>, cmp> a;
	people temp;
	temp.age = 1;
	temp.name = "test1";
	a.push(temp); // 把这个数据插入优先队列
	
	temp.age = 3;
	temp.name = "test2";
	a.push(temp); // 把这个数据插入优先队列
	
//	输出队头
	cout << a.top().name << " " << a.top().age << endl; 
	
	
	return 0;
} 

七、set集合:每种元素最多出现一次。可以O(logn)插入/删除/查询

set<int> s;
s.insert(1); //往set中插入一个元素
s.erase(1); // 在set中删除这个元素

if (s.count(x)) 
可以用来判断集合中有没有出现这种元素,因为集合中的元素只会出现一次,而count返回的是,这个元素在集合中出现的次数

八、multiset集合:每种元素最多出现不限次数,可以O(logn)插入/删除/查询

multiset<int> s;
s.insert(1); //往multiset中插入一个元素
s.erase(1); // 在multiset中删除这个元素

if (s.count(x)) 

九、map:提供一对一的哈希。map的调用/赋值均为O(logn)复杂度

map<int, int> m; 前一个为key,后一个为value
map[1] = 2;
map[999999] = 3;

但是要注意,这里的key一定得是一个可以比较的东西(map里面会有排序)

十、迭代器 : iterator (迭代器是指针,解除引用就可以取出所指向的东西)

set<int> s;
s.insert(123);
set<int>::iterator it = s.begin();
cout << (*it) << endl;


注意在map中的迭代器返回的是一个pair(pair 就是一个对(可以理解为结构体),pair<int, int> p等等。。。)
pair 会先按第一个从小到大排序,遇到相等的再按第二个来比较

cout << (*it).first <<  endl; // 输出key
cout << (*it).second << endl; // 输出value

lower_bound(x) 二分查找 返回大于等于x的最小值(第一个数),这里拿到的是迭代器
cout << (*s.lower_bound(4)) << endl;  s是一个set,可以自己去模拟一下

upper_bound(x) 返回的是大于x的第一个数的最小值,返回的也是迭代器
  • 不管是lower_bound还是upper_bound找不到这个数,就会返回stl.end(),即代表找不到这个数
  • !!!:在vector里面这个迭代器是可以做减法的,因为vector是线性结构,不像set
vector<int> v;
int idx = v.lower_bound(x) - v.begin(); 这样相当于可以返回找到的这个数的下标
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值