0%

STL

STL

vector容器

创建vector容器

1.导入头文件

1
#include <vector>

2.构造vector容器

1
vector<int> v1;		//空的容器,里面没有元素
1
vector<int> v2(100);	//100个元素数据,默认都为0
1
vector<int> v3(100,8);	//100个值为8的元素
1
vector<int> v4(v3);		//100个值为8的元素
1
2
int nTmpAry[] = {11, 12, 13, 14, 15, 16, 17, 18, 19, 20};
vector<int> v5(nTmpAry + 2, nTmpAry + 5);

image-20240718153228054

vector容器添加元素

1.push_back

1
v1.push_back(i);

将元素添加到v1容器的尾部

将元素i添加到v1的尾部

2.insert()

1
v1.insert(v1.begin(), 99);

从v1的第一个元素开始插入一个99

1
v1.insert(v1.begin() + 3, 2, 98);

从v1开始向后偏移三个的位置开始插入两个元素,98

用数组插入

1
v1.insert(v1.begin, nTmpAry+3, nTmpAry+5);

3.pop_back()

删除容器尾部的元素

1
v1.pop_back();

删除v1尾部最后一个元素

4.erase()

删除指定位置的元素

1
vi.erase(v1.begin() + 3);

删除起始位置向后偏移三个位置的数值

删除多个元素

需要指定一个范围,同时删除指定区间的元素

1
v1.erase(v1.begin(), v1.begin() + 2);

上面一条代码为:删除v1容器前两条元素。第一个索引位置的元素会被删掉,第二个索引位置前一个位置的元素会被删掉,第二个索引位置上的元素不会被删掉。

vector容器的遍历

1
2
3
4
for (int i = 0, i < v1.size(); i++)
{
printf("%3d" ,v1(i));
}
1
2
3
4
for (int i = 0, i < v1.size(); i++)
{
printf("%3d" ,v1.at(i));
}

直接遍历v1或者使用at()

使用迭代器

1
2
3
4
5
vector<int>:: iterator nIt = v1.begin();
while(nIt != v1.end())
{
printf("%3d ", nIt++)
}

deque容器

所有适用于vector的操作都适用于deque容器,将所有上述vector中的所有vector改成deque仍能正确运行

deque容器概述

1.deque是”double-ended queue”的缩写。在两端增删元素具有较佳的性能

2.模拟动态数组,与vector相似,所有适用于vector的操作都适用于deque

3.deque还有push_font(将元素插到最前面)和pop_font(删除最前面的元素)的操作

方法

push_front()
1
v1.push_front(i);

将i这个元素添加到v1的头部

pop_front()

1
v1.pop_front();

删除v1容器头部的元素

List容器

1.List是双向链表。
2.不支持随机存取,不支持at.[pos]函数和[]操作符
3.ist除了具有所有顺序容器都有的成员函数以外,还支持下面成员函数。
push front::在前而插入
pop_front:删除前而的元素
sort:排序(Iist单独实现)
remove:删除和指定值相等的元素
unique:删除所有和前一个元素相同的元素
merge:合并两个链表,并清空被合并的那个(Iist单独实现)
reverse:颠倒链表

list链表不支持v1.erase(v1.begin() + 3);这种写法,需要使用迭代器

image-20240916214515246

可以定义一个函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <windows.h>
#include <list>

using namespace std;

list<int>::iterator MoveIteractor(list<int>::iterator* pIt, int n)
{
for (int i = 0; i < n; i++)
{
(*pIt)++;
}
return *pIt;
}

void printList(list<int> myList)
{
// 迭代器遍历
list<int>::iterator nIt = myList.begin();
while (nIt!= myList.end())
{
printf("%d ", *nIt++);
}
}

int main(void)
{
list<int> myList = { 1, 2, 3, 4, 5 };

list<int>::iterator it = myList.begin();
myList.erase(MoveIteractor(&it, 2));
printList(myList);

}

这样,v1.erase(v1.begin() + 3);可以写成v1.erase(MoveIteractor(&v1.begin(), 3));

方法

1.sort()

对list进行排序

1
v1.sort();

2.remove()

删除和指定值相等的元素

1
2
3
4
list<int> myList = { 1, 2, 3, 4, 5 };
// myList => 1 2 3 4 5
myList.remove(3)
// myList => 1 2 4 5

3.unique()

删除所有和前一个元素相同的元素

1
2
3
4
list<int> myList = { 1, 2, 3, 4, 5 };
// myList => 1 2 3 4 5 5
myList.unique()
// myList => 1 2 3 4 5
image-20240919142608882

只能删除与前一个相同的,相隔的不行

4.merge()

合并两个链表,并清空被合并的那一个

合并两个链表时必须要先对每个链表进行排序,如果直接对一下两个链表进行合并,会报错

1
2
list<int> List1 = { 1, 2, 11, 12, 13, 14, 19, 20 };
list<int> List2 = { 3, 4, 5, 18, 17 };
image-20240919143746884

所以需要先对每个链表进行排序,然后再合并

合并后,所有数据被合并到List1中,List2被清空

image-20240919143837549

5.reverse()

颠倒链表

image-20240919144559547

set / multiset 容器

set/multiset容器使用红黑树实现的,底层时树形结构

1
2
3
4
5
内部元素有序排列,新元素插入的位置取决于它的值,查找速度快
支持通过键值实现快速读取
不可以使用at.(pos)或[]操作符
不可以直接修改容器中的值,如果希望修改一个元素值,必须先删除原有的元素,再插入新的元素
multiset支持一个键值多次出现

构建set容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <set>
#include <algorithm>
using namespace std;
// set容器构造函数

void printset(int a)
{
printf("%d ", a);
}

void set_constructor()
{
set<int> s1; // 构造了一个空的容器,默认使用小于比较器(元素是从小到大排序)
set<int, less<int>> s2; // 构造了一个空的容器,使用自定义的小于比较器
set<int, greater<int>> s3; // 构造了一个空的容器,使用自定义的大于比较器

int nArr[5] = { 1,2,3,4,5 };
set<int> set4(nArr, nArr + 5); // 构造了一个容器,并将数组中的元素添加到容器中

for_each(set4.begin(), set4.end(), printset); // 输出容器中的元素

}

int main()
{

set_constructor();

return 0;
}

for_each在algorithm头文件中,这个头文件实现了很多STL的算法

方法

insert()

insert()函数可以在set容器中插入值,但是不能插入重复的值,如果插入了重复的值会被删掉

image-20240919150737674 image-20240919150824117

使用数组进行插入

插入后的值在s1中仍然是有序的

image-20240919151152191

erase()

删除set容器中的值

image-20240919151520353

使用迭代器删除

删除迭代器指向位置的元素

image-20240919151735724

删除两个迭代器指向之间的元素

删除区间为[it2, it3)之间的值,左闭又开

image-20240919152023872

修改

set容器不能直接修改容器内的数据,只能先删除再插入新的元素

find()

查找函数,返回的值为迭代器

image-20240920210454030

count()

可以判断一个元素在容器里是否存在,对于multiset来说可以知道制定的元素有几个

image-20240920211201726

map / multimap 容器

1
2
3
4
5
底层使用红黑树实现
元素包含两部分(key, value),key和value可以是任意类型
根据元素的key自动排序,因此根据元素的key进行定位很快,但根据value定位很慢
不能直接改变key,可以通过[]操作符直接存取元素的值
map中不允许key相同的元素,multimap允许key相同的元素
1
mutimap<int, string, less<int>> ms;