【C++】STL容器详解【下】

目录

一、list容器

[1.1 list基本概念](#1.1 list基本概念)

[1.2 list构造函数](#1.2 list构造函数)

[1.3 list数据元素插入和删除操作](#1.3 list数据元素插入和删除操作)

[1.4 list大小操作](#1.4 list大小操作)

[1.5 list赋值操作](#1.5 list赋值操作)

[1.6 list数据的存取](#1.6 list数据的存取)

[1.7 list反转排序](#1.7 list反转排序)

[二、set[红黑树] / multiset[红黑树] / unordered_set[哈希表]容器](#二、set[红黑树] / multiset[红黑树] / unordered_set[哈希表]容器)

[2.1 set基本概念](#2.1 set基本概念)

[2.2 set构造函数](#2.2 set构造函数)

[2.3 set赋值操作](#2.3 set赋值操作)

[2.4 set大小操作](#2.4 set大小操作)

[2.5 set插入和删除操作](#2.5 set插入和删除操作)

[2.6 查找操作](#2.6 查找操作)

[2.7 set自定义排序](#2.7 set自定义排序)

三、对组pair

[四、map[红黑树] / multimap[红黑树] / unordered_map[哈希表]容器](#四、map[红黑树] / multimap[红黑树] / unordered_map[哈希表]容器)

[4.1 map基本概念](#4.1 map基本概念)

[4.1 map构造函数](#4.1 map构造函数)

[4.2 map赋值操作](#4.2 map赋值操作)

[4.3 map大小操作](#4.3 map大小操作)

[4.4 插入数据元素操作](#4.4 插入数据元素操作)

[4.5 map删除元素操作](#4.5 map删除元素操作)

[4.5 map查找元素操作](#4.5 map查找元素操作)

[4.6 map自定义排序](#4.6 map自定义排序)

五、priority_queue优先队列

[5.1 pirority_queue基本概念](#5.1 pirority_queue基本概念)

[5.2 pirority_queue构造函数](#5.2 pirority_queue构造函数)

[5.3 priority_queue赋值操作](#5.3 priority_queue赋值操作)

[5.4 priority_queue大小操作](#5.4 priority_queue大小操作)

[5.5 priority_queue插入元素操作](#5.5 priority_queue插入元素操作)

[5.6 priority_queue删除元素操作](#5.6 priority_queue删除元素操作)

[5.7 priority_queue查找元素操作](#5.7 priority_queue查找元素操作)

[5.8 priority_queue自定义排序](#5.8 priority_queue自定义排序)


一、list容器

1.1 list基本概念

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。链表由一系列节点(链表中每一个元素称为节点)组成,节点可以在运行时动态生成。每个节点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个节点地址的指针域。相较于vector的连续线性空间,list就显得负责许多,它的好处就是每次插入或者删除一个元素,就配置或者释放一个元素空间。因此,list相对于空间运用由绝对的精确,一点都不浪费。而且,对于任何位置的元素插入或者移除,list永远都是常数时间。List和Vector是两个最常用的容器。List容器是一个双向链表。

1.2 list构造函数

cpp 复制代码
list<T> lstT; //list 用模板类实现,对象的默认构造形式
list(begin, end); //构造函数将[begin, end)区间的元素拷贝给本身
list(n, elem); //构造函数将m个elem拷贝给本身
list(const list &lst); //拷贝构造函数

1.3 list数据元素插入和删除操作

cpp 复制代码
push_back(elem); //在容器尾部追加一个元素
pop_back(); //删除容器中最后一个元素
push_front(elem); //在容器头部插入一个元素
pop_front(); //在容器头部删除第一个元素
insert(pos,elem); //在pos位置插入elem元素的拷贝,返回新数据的位置
insert(pos, n, elem); //在pos位置插入n个elem元素,无返回值
insert(pos, begin, end); //在pos位置插入[begin, end)区间的数据,无返回值
clear(); //移除容器中的所有数据
erase(begin, end); //删除[begin, end)区间的元素
erase(pos); //删除pos位置的元素
remove(elem); //删除容器中所有于elem匹配的元素

1.4 list大小操作

cpp 复制代码
size(); //返回容器中元素的个数
empty(); //判断容器是否为空
resize(num); //重新指定容器长度为num,若容器边长,则以默认值填充新位置,若变短,直接截断
resize(num, elem); //重新指定容器长度为num,若容器边长,则以elem填充新位置,若变短,直接截断

1.5 list赋值操作

cpp 复制代码
assign(begin, end); //将[begin,end)区间中的数据拷贝给本身
assign(n, elem); //将n个elem拷贝给本身
list& operator=(const list &lst); //重载等号操作符
swap(lst); //将lst与本身交换

1.6 list数据的存取

cpp 复制代码
front(); // 返回第一个元素
back(); //返回最后一个元素

1.7 list反转排序

cpp 复制代码
reverse(); //反转链表
sort(); //list排序

二、set[红黑树] / multiset[红黑树] / unordered_set[哈希表]容器

2.1 set基本概念

set特性是,所有元素都会根据元素的键值自动排序,set的元素既是键值又是实值。set不允许有两个相同的键值。

multiset特性及用法和set完全一致,唯一差别在于它允许键值重复。

unordered_set和set操作类似,不同在于unordered_不会自动按照键值排序。因此,没有lower_bound和upper_bound操作。

2.2 set构造函数

cpp 复制代码
set<T, less<T>> st; //set升序排序
set<T, greater<T>> st; //set降序排序
multiset<T> mst; //multiset默认构造函数
set(const set &st); //拷贝构造函数

2.3 set赋值操作

cpp 复制代码
set& operator=(const set &st); //重载等号操作符
swap(st); //交换两个集合容器

2.4 set大小操作

cpp 复制代码
size(); //返回容量中元素的数目
empty(); //判断容器是否为空

2.5 set插入和删除操作

cpp 复制代码
insert(elem); //在容器中插入元素
clear(); //清除所有的元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(begin, end); //删除[begin, end)区间的所有元素,返回下一个元素的迭代器
erase(elem); //删除容器中值为elem的元素

2.6 查找操作

cpp 复制代码
find(key); //查找键key是否存在,若存在,返回键的元素的迭代器,若不存在,但会set.end()
count(key); //查找键key的的元素个数
lower_bound(keyElem); //返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem); //返回第一个key>keyElem元素的迭代器
equal_range(keyElem); //返回容器中key与keyElem相等的上下限的两个迭代器

2.7 set自定义排序

cpp 复制代码
// 自定义比较器,按降序排列健
struct DescendingCompare{
    bool operator<(const int& lhs, const int& rhs)const {
        return lhs > rhs; //降序排列
    }
};

int main(){
    // 使用自定义比较器的map
    std::set<int, DescendingCompare> st;
    return 0;
}

三、对组pair

对组pair将一堆值组合成一个值,这一对值可以具有不同的数据类型,两个值可以分别用piar的两个公共属性first和second模板:template<class T1, class T2>stryct pair。

如何创建pair队组?

cpp 复制代码
//第一种方法创建一个对组
pair<string, int> pair1(string("name"), 20);
cout<<pair1.first<<endl;
cout<<pair1.second<<endl;
//第二种
pair<string, int> pair2 = make_pair("name", 10);
cout<<pair2.first<<endl;
cout<<pair2.second<<endl;
//pair=赋值
pair<string, int> pair3 = pair2;
cout<<pair3.first<<endl;
cout<<pair3.second<<endl;

四、map[红黑树] / multimap[红黑树] / unordered_map[哈希表]容器

4.1 map基本概念

map的特性是,所有的元素都会根据元素的键值自动排序,Map所有的元素都是pair,同事拥有实键和键值,pair的第一个元素被视为键值,第二元素被视为实值,map不允许两个元素有相同的键值。

我们可以通过map的迭代器改变map的键值吗?

答案是不行的,因为map的键值关系到map的排序规则,任意改变map键值将会严重破坏map的组织。如果想要修改元素的实值,那么是可以的。Map和list拥有相同的某些性质,当它的容器元素进行新增操作或者删除操作时,操作之前的所有迭代器,在操作之后依然有效,当然被删除的那个元素的迭代器必然是个例外。

Multimap和map操作类似,唯一的区别multimap键值可以重复。

unordered_map和map操作类似,不同在于unordered_map不会自动按照键值排序。因此,没有lower_bound和upper_bound操作。

4.1 map构造函数

cpp 复制代码
map<T1, T2, less<T1>> mapTT; //map升序排序
map<T1, T2, greater<T1>> mapTT; //map降序排序
map(const map &mp); //拷贝构造函数

4.2 map赋值操作

cpp 复制代码
map& operator=(const map &mp); //重载等号操作符
swap(mp); //交换两个集合容器

4.3 map大小操作

cpp 复制代码
size(); //返回容器元素的数目
empty(); //判断容器是否为空

4.4 插入数据元素操作

cpp 复制代码
map.insert(...); //往容器种插入元素,返回pair<iterator, bool>
map<int, string> mapStu;
//第一种 通过pair的方式插入对象
mapStu.insert(pair<int, string)(3, "校长");
//第二种 通过pair的方式插入对象
mapStu.insert(make_pair(-1,"小河"));
//第三种 通过value_type方式插入对象
mapStu.insert(map<int, string>::value_type(1,"夏鸥"));
//第四种 通过数组的方式
mapStu[3] = "阿迪斯"

4.5 map删除元素操作

cpp 复制代码
clear(); //清除所有的元素
erase(pos); //删除pos迭代器所指的元素,返回下一个元素的迭代器
erase(begin, end); //删除[begin, end)区间的所有元素,返回下一个元素的迭代器
erase(elem); //删除容器中key为elem的元素

4.5 map查找元素操作

cpp 复制代码
find(key); //查找键key是否存在,若存在,返回键的元素的迭代器,若不存在,但会map.end()
count(key); //查找键key的的元素个数
lower_bound(keyElem); //返回第一个key>=keyElem元素的迭代器
upper_bound(keyElem); //返回第一个key>keyElem元素的迭代器
equal_range(keyElem); //返回容器中key与keyElem相等的上下限的两个迭代器

4.6 map自定义排序

自定义比较器是一个可调用对象(如函数对象、lambda 表达式或函数指针),它需要重载 operator() 并接受两个键作为参数,返回一个布尔值。这个布尔值表示第一个键是否应该在第二个键之前。

cpp 复制代码
// 自定义比较器,按降序排列健
struct DescendingCompare{
    bool operator<(const int& lhs, const int& rhs)const {
        return lhs > rhs; //降序排列
    }
};

int main(){
    // 使用自定义比较器的map
    std::map<int, std::string, DescendingCompare> mp;
    return 0;
}

五、priority_queue优先队列

5.1 pirority_queue基本概念

优先队列与queue不同的就在于我们可以自定义其中数据的优先级,让优先级高的排在队列前面,优先出队。

priority_queue具有queue的所有特性,包括基本操作,只是在这基础上添加了内部的一个排序,本质是一个堆实现的。

5.2 pirority_queue构造函数

cpp 复制代码
priority_queue<T, vector<T>, greater<T>> que; //构造升序队列
priority_queue<T, vector<T>, less<T>> que; //构造降序队列
// greater和less是std实现的两个仿函数
//(就是使一个类的使用看上像一个函数,其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)
priority_queue& (const priority_queue other); //拷贝构造函数

5.3 priority_queue赋值操作

cpp 复制代码
priority_queue& operator=(const priority_queue &que); //重载等号操作符
swap(priority_queue &que); //将que与自身交换

5.4 priority_queue大小操作

cpp 复制代码
size(); //返回队列内元素个数
empty(); //判断队列是否为空

5.5 priority_queue插入元素操作

cpp 复制代码
push(elem); //插入元素到队尾(并自动排序)
emplace(elem); //就地构造一个新元素并插入到优先队列中

5.6 priority_queue删除元素操作

cpp 复制代码
pop(); //弹出对头元素

5.7 priority_queue查找元素操作

cpp 复制代码
top(); //访问队头元素

5.8 priority_queue自定义排序

cpp 复制代码
// 自定义比较器,小顶堆
struct DescendingCompare{
    bool operator<(const int& lhs, const int& rhs)const {
        return lhs > rhs; //降序排列
    }
};

int main(){
    // 使用自定义比较器的priority_queue
    priority_queue<int, vector<int>, DescendingCompare> mp;
    return 0;
}
相关推荐
小灰灰爱代码22 分钟前
C++——求3个数中最大的数(分别考虑整数、双精度数、长整数的情况),用函数模板来实现。
开发语言·c++·算法
BeyondESH2 小时前
Linux线程同步—竞态条件和互斥锁(C语言)
linux·服务器·c++
豆浩宇2 小时前
Halcon OCR检测 免训练版
c++·人工智能·opencv·算法·计算机视觉·ocr
WG_172 小时前
C++多态
开发语言·c++·面试
Charles Ray4 小时前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
重生之我在20年代敲代码4 小时前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
迷迭所归处9 小时前
C++ —— 关于vector
开发语言·c++·算法
CV工程师小林10 小时前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
white__ice11 小时前
2024.9.19
c++
天玑y11 小时前
算法设计与分析(背包问题
c++·经验分享·笔记·学习·算法·leetcode·蓝桥杯