11. swap
void swap(list& x);
是 std::list
容器的成员函数,用于交换当前列表与另一个列表 x
的内容。
参数说明:
x
:要与当前列表进行内容交换的另一个列表。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList1 = {1, 2, 3}; std::list<int> myList2 = {4, 5, 6}; myList1.swap(myList2); // 交换两个列表的内容 std::cout << "myList1: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; std::cout << "myList2: "; for (int num : myList2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在上述示例中,myList1
和 myList2
的内容被交换,导致输出中显示的内容分别为 4 5 6
和 1 2 3
。这个函数对于在不同列表之间交换内容非常有用。
12. resize
void resize(size_type n, value_type val = value_type());
是 std::list
容器的成员函数,用于调整列表的大小。
参数说明:
n
:指定调整后的大小。
val
:在列表扩展时,用于填充新元素的值。默认值为 value_type()
,即类型的默认构造函数创建的值。
该函数通过在列表的末尾添加或删除元素,使列表的大小调整为指定的大小 n
。如果新的大小大于当前大小,新元素将用指定的值 val
填充。如果新的大小小于当前大小,多余的元素将被删除。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 4, 5}; myList.resize(3); // 调整列表大小为3 std::cout << "myList after resize to 3: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; myList.resize(5, 0); // 调整列表大小为5,并用0填充新元素 std::cout << "myList after resize to 5 with filling 0: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在上述示例中,首先调用 resize(3)
后,列表中只有前3个元素保留,然后调用 resize(5, 0)
后,列表中总共有5
个元素,其中新添加的2
个元素被填充为0
。
13. clear
void clear();
是 std::list
容器的成员函数,用于清空列表中的所有元素,使列表变为空列表。
该函数会删除列表中的所有元素,使列表变为空,但并不会释放列表所占用的内存空间,所以列表的容量不会变化。这可以有效地回收元素所占用的资源,但保留容量可以减少频繁的内存分配和释放操作,以提高性能。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 4, 5}; std::cout << "myList before clear: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; myList.clear(); // 清空列表 std::cout << "myList after clear: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在上述示例中,首先输出了清空前的列表元素,然后调用 clear()
后,列表中的所有元素被删除,输出了清空后的列表元素,此时列表为空。
list操作函数(Operations)
1. splice
void splice (iterator position, list& x);
该成员函数用于将另一个列表 x
中的所有元素移动到当前列表中,插入到指定位置 position
前。x
列表在移动后会变为空列表。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList1 = {1, 2, 3}; std::list<int> myList2 = {4, 5, 6}; auto it = myList1.begin(); std::advance(it, 2); myList1.splice(it, myList2); // 将 myList2 的元素插入到 myList1 中 std::cout << "myList1 after splice: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; std::cout << "myList2 after splice: "; for (int num : myList2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
void splice (iterator position, list& x, iterator i);
该成员函数用于将另一个列表 x
中的元素移动到当前列表中,插入到指定位置 position
前,但只移动另一个列表 x
中的迭代器 i
指向的元素。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList1 = {1, 2, 3}; std::list<int> myList2 = {4, 5, 6}; auto it1 = myList1.begin(); std::advance(it1, 1); auto it2 = myList2.begin(); myList1.splice(it1, myList2, it2); // 将 myList2 中的第一个元素插入到 myList1 中 std::cout << "myList1 after splice: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; std::cout << "myList2 after splice: "; for (int num : myList2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
void splice (iterator position, list& x, iterator first, iterator last);
该成员函数用于将另一个列表 x
中的一段元素范围 [first, last)
移动到当前列表中,插入到指定位置 position
前。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList1 = {1, 2, 3}; std::list<int> myList2 = {4, 5, 6}; auto it1 = myList1.begin(); std::advance(it1, 1); auto it2_first = myList2.begin(); auto it2_last = myList2.begin(); std::advance(it2_last, 2); myList1.splice(it1, myList2, it2_first, it2_last); // 将 myList2 中的前两个元素插入到 myList1 中 std::cout << "myList1 after splice: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; std::cout << "myList2 after splice: "; for (int num : myList2) { std::cout << num << " "; } std::cout << std::endl; return 0; }
这些 splice
函数允许你在列表中移动元素,从一个列表中移动到另一个列表中,或在同一列表内重新排列元素的位置,而不需要进行元素的复制和删除。
2. remove
void remove (const value_type& val);
该成员函数用于从列表中移除所有等于给定值 val
的元素。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 2, 4, 2, 5}; myList.remove(2); // 移除列表中所有值为 2 的元素 std::cout << "myList after remove: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,myList
列表中的值为 2
的元素被移除,最终输出为 "1 3 4 5"
。
3. remove_if
template <class Predicate> void remove_if (Predicate pred);
这个成员函数用于根据给定的谓词函数 pred
移除满足特定条件的元素。
谓词函数 pred
接受一个参数并返回一个布尔值,用于判断是否需要移除该元素。如果谓词返回 true
,则该元素将被移除。
示例用法:
#include <iostream> #include <list> bool isEven(int num) { return num % 2 == 0; } int main() { std::list<int> myList = {1, 2, 3, 4, 5, 6, 7, 8, 9}; myList.remove_if(isEven); // 移除列表中所有偶数 std::cout << "myList after remove_if: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,myList
列表中的偶数元素被移除,最终输出为 "1 3 5 7 9"
。函数 isEven
是一个谓词函数,用于判断是否为偶数。
4. unique
void unique();
这个成员函数用于移除列表中相邻的重复元素。它只保留第一个出现的重复元素,移除后续的重复元素。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 2, 3, 4, 4, 4, 5}; myList.unique(); // 移除相邻的重复元素 std::cout << "myList after unique: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,myList
列表中的相邻重复元素被移除,最终输出为 "1 2 3 4 5"
。
template <class BinaryPredicate> void unique (BinaryPredicate binary_pred);
这个成员函数在移除相邻重复元素时,使用自定义的二元谓词函数 binary_pred
来判断是否为重复元素。该谓词函数接受两个参数,并返回一个布尔值,用于判断两个元素是否相等。
示例用法:
#include <iostream> #include <list> bool isEqual(int a, int b) { return a == b; } int main() { std::list<int> myList = {1, 2, 2, 3, 4, 4, 4, 5}; myList.unique(isEqual); // 使用 isEqual 判断是否为重复元素 std::cout << "myList after unique with custom predicate: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,通过自定义的谓词函数 isEqual
判断相邻的元素是否相等,移除相邻的重复元素,最终输出为 "1 2 3 4 5"
。
5. merge
void merge(list& x);
这个成员函数用于将另一个列表 x
合并到当前列表中,合并后的列表会按照升序排列。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList1 = {1, 3, 5}; std::list<int> myList2 = {2, 4, 6}; myList1.merge(myList2); // 将 myList2 合并到 myList1 中 std::cout << "myList1 after merge: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,myList2
列表被合并到了 myList1
中,合并后的列表按照升序排列,最终输出为 "1 2 3 4 5 6"
。
template <class Compare> void merge(list& x, Compare comp);
这个成员函数与上面的 merge
函数类似,但是它允许提供一个自定义的比较函数 comp 来决定合并后的顺序。
示例用法:
#include <iostream> #include <list> bool descendingOrder(int a, int b) { return a > b; } int main() { std::list<int> myList1 = {5, 3, 1}; std::list<int> myList2 = {6, 4, 2}; myList1.merge(myList2, descendingOrder); // 使用自定义比较函数合并 std::cout << "myList1 after merge with custom comparison: "; for (int num : myList1) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,通过自定义的比较函数 descendingOrder
,将 myList2
列表合并到了 myList1
中,合并后的列表按照降序排列,最终输出为 "6 5 4 3 2 1"
。
6. sort
void sort();
这个成员函数用于对列表进行升序排序,默认使用 <
运算符进行比较。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {5, 3, 1, 4, 2}; myList.sort(); // 对列表进行升序排序 std::cout << "myList after sorting: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,列表中的元素经过排序后变为 "1 2 3 4 5"
。
template <class Compare> void sort(Compare comp);
这个成员函数与上面的 sort
函数类似,但是它允许提供一个自定义的比较函数 comp
来决定排序的顺序。
示例用法:
#include <iostream> #include <list> bool descendingOrder(int a, int b) { return a > b; } int main() { std::list<int> myList = {5, 3, 1, 4, 2}; myList.sort(descendingOrder); // 使用自定义比较函数进行降序排序 std::cout << "myList after custom sorting: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,通过自定义的比较函数 descendingOrder
,列表中的元素经过排序后变为 "5 4 3 2 1"
。
7. reverse
void reverse();
函数用于将列表中的元素逆序排列。
示例用法:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 4, 5}; myList.reverse(); // 将列表中的元素逆序排列 std::cout << "myList after reversing: "; for (int num : myList) { std::cout << num << " "; } std::cout << std::endl; return 0; }
在示例中,列表中的元素经过逆序排列后变为 "5 4 3 2 1"
。
list的迭代器失效
迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。
当使用 std::list
进行删除操作时,可能会导致迭代器失效。下面是一个示例:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 4, 5}; auto it = myList.begin(); ++it; // Move the iterator to the second element myList.erase(it); // Erase the second element for (auto num : myList) { std::cout << num << " "; } return 0; }
在上面的示例中,当我们在第二个元素位置处使用 erase
函数删除元素后,迭代器 it
就会失效,因为它指向的元素已经被删除。如果我们尝试使用失效的迭代器,可能会导致未定义的行为。
要修正这个问题,可以使用 erase
函数的返回值,它会返回一个指向下一个有效元素的迭代器:
#include <iostream> #include <list> int main() { std::list<int> myList = {1, 2, 3, 4, 5}; auto it = myList.begin(); ++it; // Move the iterator to the second element it = myList.erase(it); // Erase the second element and update the iterator for (auto num : myList) { std::cout << num << " "; } return 0; }
在这个修正后的示例中,我们使用 erase
函数的返回值更新了迭代器 it
,以确保它指向的是有效的元素。这样就避免了使用失效迭代器引发的问题。
结语
有兴趣的小伙伴可以关注作者,如果觉得内容不错,请给个一键三连吧,蟹蟹你哟!!!
制作不易,如有不正之处敬请指出
感谢大家的来访,UU们的观看是我坚持下去的动力
在时间的催化剂下,让我们彼此都成为更优秀的人吧!!!