C++之STL整理(9)之list用法(创建、赋值、增删查改)详解

注:整理一些突然学到的C++知识,随时mark一下
例如:忘记的关键字用法,新关键字,新数据结构


C++ 的list用法整理


提示:本文为 C++ 中 list构造、赋值、接口 的写法和举例


一、 list 对象的创建

  STL 中的std::list 是 C++ 标准模板库(STL)中的一种双向链表数据结构,可以任意位置高效插与删。它提供了许多操作来管理链表中的元素,如插、删、遍历等。以下是对 std::list 及其相关函数的详细解释,并给出每个函数的简单使用例子:

list 构造函数

1.1 默认构造函数

std::list<int> lst; // 创建一个空的 int 类型 list

1.2 区间构造函数

int arr[] = {1, 2, 3, 4, 5};  
std::list<int> lst(arr, arr + 5); // 创建一个包含数组元素的 list

1.3 拷贝指定元素次数的构造函数

std::list<int> lst(10, 5); // 创建一个包含 10 个 5 的 list

1.4 拷贝构造函数

std::list<int> lst1(10, 5);  
std::list<int> lst2(lst1); // 创建一个 lst1 的副本 lst2

二、list 数据元素的增删查改

2.1 尾部插入元素

std::list<int> lst;  
lst.push_back(1); // 在 lst 尾部插入元素 1

2.2 删尾部元素

lst.push_back(2); // lst 现在为 {1, 2}  
lst.pop_back(); // 删 lst 的最后一个元素,lst 现在为 {1}

2.3 开头插入元素

lst.push_front(0); // 在 lst 开头插入元素 0,lst 现在为 {0, 1}

2.4 删开头元素

lst.pop_front(); // 删 lst 的第一个元素,lst 现在为 {1}

2.5 在指定位置插入元素

std::list<int>::iterator it = lst.begin();  
lst.insert(it, 2); // 在 lst 的开头插入元素 2,lst 现在为 {2, 1}

2.6 在指定位置插入多个元素

lst.insert(lst.end(), 3, 3); // 在 lst 尾部插入 3 个元素 3,lst 现在为 {2, 1, 3, 3, 3}

2.7 在指定位置插入区间元素

std::list<int> lst2 = {4, 5, 6};  
lst.insert(lst.begin(), lst2.begin(), lst2.end()); // 在 lst 开头插入 lst2 的元素,lst 现在为 {4, 5, 6, 2, 1, 3, 3, 3}

2.8 清空所有元素

lst.clear(); // lst 现在是空的

2.9 删指定区间元素

lst.push_back(4); lst.push_back(5); lst.push_back(6); // lst 现在是 {4, 5, 6}  
lst.erase(lst.begin(), std::next(lst.begin(), 2)); // 删从开头到第二个元素之后的位置,lst 现在为 {6}

2.10 删指定位置元素

lst.push_back(7); // lst 现在是 {6, 7}  
lst.erase(std::prev(lst.end())); // 删最后一个元素之前的元素,lst 现在为 {7}

2.11 删所有匹配元素

lst.push_back(7); lst.push_back(7); // lst 现在是 {7, 7}  
lst.remove(7); // 删所有值为 7 的元素,lst 现在是空的

std::list 提供了丰富的操作来管理链表中的元素,这些操作都是高效的,因为 std::list 的节点存储了指向前后节点的指针,使得插入和删操作可以在常数时间内完成。在需要频繁进行插入和删操作的场景下,std::list 通常是一个很好的选择。

三、 list 大小操作

3.1 返回容器中元素的个数

std::list<int> lst = {1, 2, 3, 4, 5};  
std::size_t size = lst.size(); // size 为 5

3.2 判断容器是否为空

std::list<int> empty_lst;  
if (empty_lst.empty()) {  
    // 此代码块会被执行,因为 empty_lst 是空的  
}

3.3 重新指定容器的长度为指定值(默认填充)

std::list<int> lst = {1, 2, 3};  
lst.resize(5); // lst 现在为 {1, 2, 3, 默认值, 默认值}

3.4 重新指定容器的长度为指定值并指定填充值

std::list<int> lst = {1, 2, 3};  
lst.resize(5, 0); // lst 现在为 {1, 2, 3, 0, 0}

四、 list 赋值操作

4.1 将区间中的数据拷贝赋值给本身

std::list<int> lst1 = {1, 2, 3};  
std::list<int> lst2;  
lst2.assign(lst1.begin(), lst1.end()); // lst2 现在为 {1, 2, 3}

4.2 将指定个数的元素拷贝赋值给本身

std::list<int> lst;  
lst.assign(3, 4); // lst 现在为 {4, 4, 4}

4.3 重载等号操作符进行赋值

std::list<int> lst1 = {1, 2, 3};  
std::list<int> lst2;  
lst2 = lst1; // lst2 现在为 {1, 2, 3}

4.4 交换两个 list 的元素

std::list<int> lst1 = {1, 2, 3};  
std::list<int> lst2 = {4, 5, 6};  
lst1.swap(lst2); // lst1 现在为 {4, 5, 6},lst2 现在为 {1, 2, 3}

五、 list 数据的存取

5.1 返回第一个元素

std::list<int> lst = {1, 2, 3};  
int first_elem = lst.front(); // first_elem 为 1

5.2 返回最后一个元素

int last_elem = lst.back(); // last_elem 为 3

六、list 反转与排序

6.1 反转链表

std::list<int> lst = {1, 2, 3, 4, 5};  
lst.reverse(); // lst 现在为 {5, 4, 3, 2, 1}

6.2 对链表进行排序

std::list<int> lst = {5, 3, 1, 4, 2};  
lst.sort(); // lst 现在为 {1, 2, 3, 4, 5}

需要注意的是,std::list 的 sort 方法只适用于包含可比较元素的列表。对于自定义类型的元素,你需要提供比较函数或重载比较操作符,以便 sort 方法能够正确地对元素进行排序。

总结

std::list 的这些操作提供了灵活且高效的方式来管理链表结构的数据,使得在需要频繁进行插入和删除操作的场景中,std::list 成为一个非常合适的选择。

04-21 00:49