C++ list(双向链表)

打印 上一主题 下一主题

主题 1512|帖子 1512|积分 4546

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
概念

std::list 是标准模板库(STL)提供的一个容器类,它实现了双向链表的数据结构。
实现原理

内部结构


双向链表由多个节点连接而成。此中每个节点包含三个部分:


  • 内容/数据域:用于存储实际的数据元素。
  • 前驱:指向前一个节点的指针。
  • 后继:指向后一个节点的指针。
节点管理

当创建一个 std::list 对象时,它会维护一个头节点和尾节点,用于标志链表的起始和竣事位置。头节点和尾节点通常是虚拟节点,不存储实际的数据,仅用于简化链表的操纵。
插入操纵



  • 在头部插入:创建一个新节点,将新节点的 next 指针指向原来的头节点的下一个节点,将原来头节点的下一个节点的 prev 指针指向新节点,然后更新头节点的 next 指针指向新节点,新节点的 prev 指针指向头节点。
  • 在尾部插入:创建一个新节点,将新节点的 prev 指针指向原来的尾节点的前一个节点,将原来尾节点的前一个节点的 next 指针指向新节点,然后更新尾节点的 prev 指针指向新节点,新节点的 next 指针指向尾节点。
  • 在中间插入:先找到插入位置的节点,创建一个新节点,调整新节点和相邻节点的 prev 和 next 指针,以将新节点插入到符合的位置。

删除操纵



  • 删除头部元素:找到头节点的下一个节点,将头节点的 next 指针指向该节点的下一个节点,将该节点下一个节点的 prev 指针指向头节点,然后释放该节点的内存。



  • 删除尾部元素:找到尾节点的前一个节点,将尾节点的 prev 指针指向该节点的前一个节点,将该节点前一个节点的 next 指针指向尾节点,然后释放该节点的内存。
  • 删除中间元素:找到要删除的节点,调整其相邻节点的 prev 和 next 指针,跳过该节点,然后释放该节点的内存。
查找操纵

重新节点开始遍历整个链表,直到找到指定元素或遍历完整个链表。
基本操纵与方法接口

定义、初始化和赋值

  1. #include <iostream>
  2. #include <list>
  3. int main()
  4. {
  5.     // 定义一个空的 list,存储 int 类型的元素
  6.     std::list<int> List1;
  7.     // 定义并初始化一个包含 5 个元素,每个元素都是默认值(0)的 list
  8.     std::list<int> List2(5);
  9.     // 定义并初始化一个包含 5 个元素,每个元素的值都是 10 的 list
  10.     std::list<int> List3(5, 10);
  11.     // 用另一个 list 初始化新的 list
  12.     std::list<int> List4(List3);
  13.     // 用另一个 list 的迭代器范围初始化新的 list
  14.     std::list<int> List5(List4.begin(), List4.end());
  15.     // 使用"拷贝初始化"初始化 list
  16.     std::list<int> List6 = { 1, 2, 3, 4, 5 };
  17.    
  18.     // 使用"直接列表初始化"初始化 list
  19.     std::list<int> List7{ 1, 2, 3, 4, 5 };
  20. }
复制代码
元素访问

front

访问第一个元素
  1. List.front()
  2. List.front() = 6;   //将第一个元素赋值为6
复制代码
back

访问最后一个元素
  1. List.back();
  2. List.back() = 6;   //将最后一个元素赋值为6
复制代码
迭代器


list 的节点在内存中是离散分布的,只能通过节点的指针依次访问相邻的节点。因此,其迭代器只支持双向访问,即可以使用 ++ 和 -- 操纵符将迭代器向前或向后移动一个位置,但不支持随机访问操纵。以下是 list  迭代器不支持的操纵:
算术运算:不能使用 + 和 - 运算符将迭代器直接移动多个位置,由于要访问指定位置的元素,必须从当前位置开始,沿着链表依次遍历,时间复杂度为 (O(n))(较高)。如果非要使用 +- 运算,可以使用 std::advance 泛型算法。
部分比较运算:虽然可以使用 == 和 != 来判定两个迭代器是否相等,但不支持 >、<、<=、>= 等比较运算符,由于链表节点在内存中没有一连的地址顺序,无法直接比较位置关系。
正向迭代器

begin:返回容器中第一个元素的正向迭代器
end:返回容器中最后一个元素的后一个位置的正向迭代器
  1. #include <iostream>
  2. #include <list>
  3. int main()
  4. {
  5.     std::list<int> List(5);
  6.     // 使用正向迭代器为list赋值
  7.     for (std::list<int>::iterator it = List.begin(); it != List.end(); ++it)
  8.     {
  9.         *it = 3;
  10.     }
  11.     // 使用正向迭代器遍历list并打印其值
  12.     for (std::list<int>::iterator it = List.begin(); it != List.end(); ++it)
  13.     {
  14.         std::cout << *it << " ";
  15.     }
  16.     std::cout << std::endl;
  17. }
复制代码

cbegin:返回容器中第一个元素的正向常量迭代器
cend:返回容器中最后一个元素的后一个位置的正向常量迭代器
常量迭代器的特点是,它只能用于读取元素,不能通过它来修改所指向的元素,这有助于在必要保证数据不被修改的场景下使用。
  1. #include <iostream>
  2. #include <list>
  3. int main()
  4. {
  5.     std::list<int> List = {1, 2, 3, 4, 5 };
  6.     // 遍历容器并输出元素
  7.     for (std::list<int>::const_iterator it = List.cbegin(); it != List.cend(); ++it)
  8.     {
  9.         // 可以读取元素
  10.         std::cout << *it << " ";
  11.         // 以下代码会编译错误,因为不能通过常量迭代器修改元素
  12.         // *it = 10;
  13.     }
  14.     std::cout << std::endl;
  15. }
复制代码

反向迭代器

rbegin:返回容器中最后一个元素的反向迭代器
rend:返回容器中第一个元素的前一个位置的反向迭代器
  1. #include <iostream>
  2. #include <list>
  3. int main()
  4. {
  5.         std::list<int> List = {1, 2, 3, 4, 5 };
  6.         std::list<int>::reverse_iterator rit = List.rbegin();
  7.         *rit = 23;
  8.        
  9.         std::cout << *rit;
  10. }
复制代码


crbegin:返回容器中第一个元素的反向常量迭代器
crend:返回容器中最后一个元素的后一个位置的反向常量迭代器
  1. #include <iostream>
  2. #include <list>
  3. int main()
  4. {
  5.         std::list<int> List = {1, 2, 3, 4, 5 };
  6.         //反向迭代器倒序遍历容器
  7.         std::list<int>::const_reverse_iterator rit1 = List.crbegin();
  8.         while (rit1 != List.crend())
  9.         {
  10.                 std::cout << *rit1 << " ";                //先打印再自增
  11.                 ++rit1;
  12.         }
  13.         std::cout << std::endl;
  14.         /*
  15.         不能使用下面的方法来正序遍历迭代器。
  16.         因为list 的迭代器是双向迭代器,不是随机访问迭代器,不能使用 rit2 - 1 这样的操作
  17.         std::list<int>::const_reverse_iterator rit2 = List.crend();
  18.         while (rit2 != List.crbegin())
  19.         {
  20.                 std::cout << *(rit2 - 1) << " ";
  21.                 --rit2;
  22.         }
  23.         std::cout << std::endl;
  24.         */
  25.         //反向迭代器正序遍历容器
  26.         std::list<int>::const_reverse_iterator rit2 = List.crend();
  27.         while (rit2 != List.crbegin())
  28.         {
  29.                 --rit2;                //先自减再打印
  30.                 std::cout << *rit2 << " ";
  31.         }
  32.         std::cout << std::endl;
  33. }
复制代码

对于反向迭代器:rbegin和crbegin到rend和crend为迭代器的正方向。rbegin和crbegin小于rend和crend,rbegin和crbegin通过自加可以到达rend和crend的位置。rend和crend大于rbegin和crbegin,rend和crend通过自减可以到达rbegin和crbegin的位置。
基于范围的for循环

留意向vector写入元素时,for循环中要加引用符&。缘故原由见:C++杂项(更新中)_std:perator==<std::vector<std::vector<int, std::-CSDN博客
  1. #include <iostream>
  2. #include <list>
  3. using namespace std;
  4. int main()
  5. {
  6.     list<int> List = {1, 2, 3, 4, 5 };
  7.     for (int num : List)
  8.     {
  9.         cout << num;
  10.     }
  11.     cout << endl;
  12.     for (int& num : List)
  13.     {
  14.         num = 9;
  15.         cout << num;
  16.     }
  17.     cout << endl;
  18.     for (int num : List)
  19.     {
  20.         cout << num;
  21.     }
  22.     cout << endl;
  23. }
复制代码

容量

empty

判定容器是否为空,如果为空则返回 true,否则返回 false。
  1. List.empty()
复制代码
size

返回当前存储的元素个数
  1. List.size()
复制代码
max_size

返回可容纳的最大元素数目,即一直向list中添加元素直到溢出时的元素个数
  1. List.max_size()
复制代码
修改器

clear

清除list中的所有内容
  1. List.clear()
复制代码
insert

在指定位置插入元素
  1. #include <iostream>
  2. #include <list>
  3. #include <array>
  4. // 打印vector中的元素
  5. void printList(const std::list<int>& List)
  6. {
  7.     for (int num : List)
  8.     {
  9.         std::cout << num << " ";
  10.     }
  11.     std::cout << std::endl;
  12. }
  13. int main()
  14. {
  15.     std::list<int> List = { 1, 2, 3, 4, 5 };
  16.     // 1. 在指定位置插入单个元素
  17.     List.insert(List.begin(), 10);
  18.     std::cout << "在指定位置插入单个元素: ";
  19.     printList(List);
  20.     // 2. 在指定位置插入多个相同值的元素
  21.     List.insert( -- List.end(), 3, 20);
  22.     std::cout << "在指定位置插入多个相同值的元素: ";
  23.     printList(List);
  24.     // 3. 在指定位置插入另一个容器的元素范围
  25.     std::array<int, 2> a = { 30, 40 };
  26.     List.insert(List.begin(), a.begin(), a.end());
  27.     std::cout << "在指定位置插入另一个容器的元素范围: ";
  28.     printList(List);
  29.     // 4. 在指定位置插入初始化列表中的元素
  30.     List.insert(List.end(), { 50, 60 });
  31.     std::cout << "在指定位置插入初始化列表中的元素: ";
  32.     printList(List);
  33. }
复制代码


emplace

原位构造元素
未完待续
emplace_back

在容器末了原位构造元素
未完待续
emplace_front

在容器头部原位构造元素
未完待续
erase

移除单个元素
  1. iterator erase(iterator position);
复制代码
position:这是一个迭代器,指向要移除的元素。
返回一个迭代器,该迭代器指向被移除元素之后的谁人元素。若移除的是列表的最后一个元素,就返回 end() 迭代器。
移除一个范围内的元素
  1. iterator erase(iterator first, iterator last);
复制代码
first 和 last:这是两个迭代器,它们定义了要移除的元素范围 [first, last)。也就是说,这个范围包含 first 指向的元素,但不包含 last 指向的元素。
返回一个迭代器,该迭代器指向被移除范围之后的第一个元素。若移除的是列表末了的元素,就返回 end() 迭代器。
  1. #include <iostream>
  2. #include <list>
  3. #include <iterator>
  4. // 打印List中的元素
  5. void printList(const std::list<int>& List)
  6. {
  7.     for (int num : List)
  8.     {
  9.         std::cout << num << " ";
  10.     }
  11.     std::cout << std::endl;
  12. }
  13. int main()
  14. {
  15.     std::list<int> List = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  16.     printList(List);
  17.     List.erase(List.begin());
  18.     printList(List);
  19.     // 保存开始迭代器向前移动2个位置的迭代器
  20.     auto it1 = List.begin();
  21.     std::advance(it1, 2);
  22.     // 保存结束迭代器向前移动3个位置的迭代器
  23.     auto it2 = List.end();
  24.     std::advance(it2, -3);
  25.     List.erase(it1, it2);
  26.     printList(List);
  27. }
复制代码

push_front

将元素添加到容器开头
  1. List.push_back("abc")    //将“abc”插入List开头
复制代码
push_back

将元素添加到容器末了
  1. List.push_back("abc")    //将“abc”插入List末尾
复制代码
pop_front

移除开头元素
  1. List.pop_front()
复制代码
pop_back

移除末了元素
  1. List.pop_back()
复制代码
resize

改变存储元素的个数
  1. #include <iostream>
  2. #include <list>
  3. #include <iterator>
  4. // 打印List中的元素
  5. void printList(const std::list<int>& List)
  6. {
  7.     for (int num : List)
  8.     {
  9.         std::cout << num << " ";
  10.     }
  11.     std::cout << std::endl;
  12. }
  13. int main()
  14. {
  15.     std::list<int> List = { 1, 2, 3 };
  16.     std::cout << "原始List: ";
  17.     printList(List);
  18.     List.resize(5);
  19.     std::cout << "增加大小到 5 后: ";
  20.     printList(List);
  21.     List.resize(2);
  22.     std::cout << "减少大小到 2 后: ";
  23.     printList(List);
  24.     List.resize(6, 4);
  25.     std::cout << "增加大小到 6 并将新增的元素赋予默认值 4 后: ";
  26.     printList(List);
  27.     List.resize(3, 3);
  28.     std::cout << "减少大小到 3 并将新增的元素(实际没有)赋予默认值 3 后: ";
  29.     printList(List);
  30. }
复制代码

swap

互换两个list中的内容
  1. #include <iostream>
  2. #include <list>
  3. #include <iterator>
  4. // 打印List中的元素
  5. void printList(const std::list<int>& List)
  6. {
  7.     for (int num : List)
  8.     {
  9.         std::cout << num << " ";
  10.     }
  11.     std::cout << std::endl;
  12. }
  13. int main()
  14. {
  15.     std::list<int> List1 = { 1, 2, 3 };
  16.     std::list<int> List2 = { 4, 5 };
  17.     List1.swap(List2);
  18.     std::cout << "List1: ";
  19.     printList(List1);
  20.     std::cout << "List2: ";
  21.     printList(List2);
  22. }
复制代码

assign

将值赋给容器
  1. #include <iostream>
  2. #include <list>
  3. #include <string>
  4. int main()
  5. {
  6.     std::list<char> List;
  7.     // 使用Lambda表达式打印list中的元素
  8.     auto print_list = [&]()
  9.     {
  10.         for (char c : List)
  11.         {
  12.             std::cout << c << ' ';
  13.         }
  14.         std::cout << '\n';
  15.     };
  16.     List.assign(5, 'a');
  17.     print_list();
  18.     const std::string extra = "hello world";
  19.     List.assign(extra.begin(), extra.end());
  20.     print_list();
  21.     List.assign({ 'C', '+', '+', '1', '1' });
  22.     print_list();
  23. }
复制代码

操纵

sort

对元素进行排序
有两种重载情势。第一种是升序排序,第2种是按照自定义的比较规则排序。
  1. void sort();
  2. template< class Compare >
  3. void sort( Compare comp );
复制代码
  1. #include <functional>   //std::greater<int>()
  2. #include <iostream>
  3. #include <list>
  4. // 打印List中的元素
  5. void printList(const std::list<int>& List)
  6. {
  7.     for (int num : List)
  8.     {
  9.         std::cout << num << " ";
  10.     }
  11.     std::cout << std::endl;
  12. }
  13. int main()
  14. {
  15.     std::list<int> List{ 8, 7, 5, 9, 0, 1, 3, 2, 6, 4 };
  16.     std::cout << "初始:";
  17.     printList(List);
  18.     List.sort();
  19.     std::cout << "升序:";
  20.     printList(List);
  21.     List.sort(std::greater<int>());
  22.     std::cout << "降序:";
  23.     printList(List);
  24. }
复制代码

merge

归并两个有序列表,准确来说是按照肯定比较规则将指定列表中的元素剪切至原列表中。
默认比较方式
  1. void merge( list& other );
  2. void merge( list&& other );
复制代码
other:要归并到当前列表的另一个 std::list 对象,可以是左值引用或右值引用。
功能:将 other 列表中的所有元素归并到当前列表中,归并后 other 列表会变为空。两个列表都必须按照默认的比较规则(通常是 operator<)进行排序。
示例代码
  1. #include <iostream>
  2. #include <list>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. int main()
  13. {
  14.     std::list<int> List1 = { 5, 9, 1, 3, 3 };
  15.     std::list<int> List2 = { 8, 7, 2, 3, 4, 4 };
  16.     List1.sort();
  17.     List2.sort();
  18.     std::cout << "list1:"; printList(List1);
  19.     std::cout << "list2:"; printList(List2);
  20.     List1.merge(List2);
  21.     std::cout << "合并后的list1:"; printList(List1);
  22.     std::cout << "合并后的list2:"; printList(List2);
  23. }
复制代码

自定义比较方式
  1. template< class Compare >
  2. void merge( list& other, Compare comp );
  3. template< class Compare >
  4. void merge( list&& other, Compare comp );
复制代码
other:要归并到当前列表的另一个 std::list 对象,可以是左值引用或右值引用。
comp:一个二元比较函数,用于定义元素的排序规则。该函数接受两个参数,返回一个布尔值,表示第一个参数是否应该排在第二个参数之前(如果返回的值为true,那么第一个参数要在第二个参数前)。
功能形貌:将 other 列表中的所有元素归并到当前列表中,归并后 other 列表会变为空。两个列表都必须按照 comp 指定的比较规则进行排序。
示例代码
  1. #include <iostream>
  2. #include <list>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. // 自定义比较函数,按降序排序
  13. bool greater(int a, int b)
  14. {
  15.     return a > b;
  16. }
  17. int main()
  18. {
  19.     std::list<int> List1 = { 5, 9, 1, 3, 3 };
  20.     std::list<int> List2 = { 8, 7, 2, 3, 4, 4 };
  21.     List1.sort(greater);
  22.     List2.sort(greater);
  23.     std::cout << "list1:"; printList(List1);
  24.     std::cout << "list2:"; printList(List2);
  25.     List1.merge(List2, greater);
  26.     std::cout << "合并后的list1:"; printList(List1);
  27.     std::cout << "合并后的list2:"; printList(List2);
  28. }
复制代码

splice

从另一个 list 中移动元素
转移整个列表
  1. void splice(const_iterator position, list& other);
  2. void splice(const_iterator position, list&& other);
复制代码
position:这是一个常量迭代器,它指定了在目标列表中插入元素的位置。
other:这是要转移元素的源列表,可以是左值引用或者右值引用。
功能:把 other 列表中的所有元素转移到目标列表的 position 位置之前,转移完成后,other 列表会变为空。
转移单个元素
  1. void splice(const_iterator position, list& other, const_iterator it);
  2. void splice(const_iterator position, list&& other, const_iterator it);
复制代码
参数说明
position:常量迭代器,指定在目标列表中插入元素的位置。
other:源列表,可以是左值引用或者右值引用。
it:常量迭代器,指向 other 列表中要转移的单个元素。
功能形貌:把 other 列表中 it 所指向的元素转移到目标列表的 position 位置之前,转移后,该元素会从 other 列表中移除。
转移元素范围
  1. void splice(const_iterator position, list& other, const_iterator first, const_iterator last);
  2. void splice(const_iterator position, list&& other, const_iterator first, const_iterator last);
复制代码
参数说明
position:常量迭代器,指定在目标列表中插入元素的位置。
other:源列表,可以是左值引用或者右值引用。
first 和 last:常量迭代器,定义了要转移的元素范围 [first, last),也就是包含 first 指向的元素,但不包含 last 指向的元素。
功能形貌:把 other 列表中 [first, last) 范围内的元素转移到目标列表的 position 位置之前,转移后,这些元素会从 other 列表中移除。
代码示例
  1. #include <iostream>
  2. #include <list>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. int main()
  13. {
  14.     std::list<int> List1 = { 1, 2, 3 };
  15.     std::list<int> List2 = { 4, 5, 6 };
  16.     // 把 List2 的所有元素转移到 List1 的开头
  17.     List1.splice(List1.begin(), List2);
  18.     std::cout << "List1: ";   printList(List1);
  19.     std::cout << "List2: ";   printList(List2);
  20.     std::list<int> List3 = { 1, 2, 3 };
  21.     std::list<int> List4 = { 4, 5, 6 };
  22.     // 把 List4 的第二个元素转移到 list1 的开头
  23.     List3.splice(List3.begin(), List4, ++List4.begin());
  24.     std::cout << "List3: ";     printList(List3);
  25.     std::cout << "List4: ";     printList(List4);
  26.     std::list<int> List5 = { 1, 2, 3, 4, 5, 6 };
  27.     std::list<int> List6 = { 7, 8, 9 };
  28.     // 把 List5 的第二个到倒数第二个之间的元素转移到 list6 的开头
  29.     List6.splice(List6.begin(), List5, ++List5.begin(), --List5.end());
  30.     std::cout << "List5: ";     printList(List5);
  31.     std::cout << "List6: ";     printList(List6);
  32. }
复制代码

remove

移除列表中所有值即是指定值的元素
C++20前,该方法没有返回值; C++20及C++20后,该方法返回移除的数目。
  1. #include <list>
  2. #include <iostream>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. int main()
  13. {
  14.     std::list<int> List = { 1, 100, 2, 3, 10, 1, 11, -1, 12 };
  15.     auto count = List.remove(1);
  16.     std::cout << "移除了 " << count << " 个等于 1 的元素\n";
  17.     printList(List);
  18. }
复制代码

remove_if

移除满足特定标准的元素
C++20前,该方法没有返回值; C++20及C++20后,该方法返回移除的数目。
  1. void remove_if( UnaryPredicate p );
  2. size_type remove_if( UnaryPredicate p );
复制代码
p:一个一元谓词函数(关于谓词函数的相干知识可以查看:C++杂项(更新中)_std:perator==<std::vector<std::vector<int, std::-CSDN博客),接受列表元素类型的参数,返回一个布尔值。如果返回 true,则表示该元素必要被移除。
  1. #include <list>
  2. #include <iostream>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. // 定义一个一元谓词函数,判断元素是否为奇数
  13. bool isOdd(int num)
  14. {
  15.     return num % 2 != 0;
  16. }
  17. int main()
  18. {
  19.     std::list<int> List = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  20.     // 移除所有奇数元素
  21.     List.remove_if(isOdd);
  22.     // 输出移除元素后的列表
  23.     printList(List);
  24. }
复制代码


reverse

逆转容器中的元素顺序
  1. List.reverse()
复制代码
unique

从列表中移除一连重复的元素,仅保留每个一连重复元素序列中的第一个元素
默认比较方式
  1. void unique();    (C++20 前)
  2. size_type unique();    (C++20 起)
复制代码
返回值:移除的元素数目。
功能:使用 operator== 来比较相邻的元素,移除所有一连重复的元素,只保留每个一连重复元素序列中的第一个元素。
  1. #include <iostream>
  2. #include <list>
  3. // 打印List中的元素
  4. void printList(const std::list<int>& List)
  5. {
  6.     for (int num : List)
  7.     {
  8.         std::cout << num << " ";
  9.     }
  10.     std::cout << std::endl;
  11. }
  12. int main()
  13. {
  14.     std::list<int> List = { 1, 1, 2, 2, 2, 3, 3, 1, 1 };
  15.     List.unique();
  16.     printList(List);
  17. }
复制代码


自定义比较方式
  1. template< class BinaryPredicate >
  2. void unique( BinaryPredicate p );    (C++20 前)
  3. template< class BinaryPredicate >
  4. size_type unique( BinaryPredicate p );    (C++20 起)
复制代码
p:一个二元谓词函数 (关于谓词函数的相干知识可以查看:C++杂项(更新中)_std:perator==<std::vector<std::vector<int, std::-CSDN博客),用于比较相邻的元素。该函数接受两个参数,返回一个布尔值,表示这两个参数是否被视为相等。
返回值:移除的元素数目。
功能:使用用户提供的二元谓词 p 来比较相邻的元素,移除所有被 p 判定为相等的一连元素,只保留每个一连重复元素序列中的第一个元素。
  1. #include <iostream>
  2. #include <list>
  3. // 自定义二元谓词,判断两个元素的绝对值是否相等
  4. bool absEqual(int a, int b)
  5. {
  6.     return std::abs(a) == std::abs(b);
  7. }
  8. // 打印List中的元素
  9. void printList(const std::list<int>& List)
  10. {
  11.     for (int num : List)
  12.     {
  13.         std::cout << num << " ";
  14.     }
  15.     std::cout << std::endl;
  16. }
  17. int main()
  18. {
  19.     std::list<int> List = { 1, -1, 2, 2, -2, 3, 3, -1, 1 };
  20.     List.unique(absEqual);
  21.     printList(List);
  22. }
复制代码

参考与引用

C++ STL list 容器详解-CSDN博客
C++——list的简介及使用_c++ list-CSDN博客
std::list - cppreference.com
百度安全验证

未完待续
写出容器方法的底层实现原理和复杂度。
未完待续

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

来自云龙湖轮廓分明的月亮

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表