当前位置:首页 » 《关于电脑》 » 正文

【C++】list常见用法

24 人参与  2024年09月18日 11:21  分类 : 《关于电脑》  评论

点击全文阅读


?个人主页?:孤寂大仙V
?收录专栏?:C++从小白到高手
?往期回顾?:[C++]vector常见用法
? 流水不争,争的是滔滔不息。

文章目录

一、list的介绍list的主要特点 二、list的使用list的构造list的迭代器使用list的空间问题list的元素访问list的插入与删除迭代器失效问题list和vector对比


一、list的介绍

在C++中,std::list 是一种双向链表数据结构,属于C++标准模板库(STL)中的容器之一。与std::vector相比,std::list在某些操作上有不同的性能特点,尤其是在频繁的插入和删除操作时具有优势。

list的主要特点

双向链表:std::list 是一个双向链表,意味着每个元素都有指向前后元素的指针。与数组不同,它不是连续的内存块。高效的插入和删除:在链表中,插入和删除元素只需要修改指针,因此在任意位置插入或删除元素的效率较高,特别是当操作位置已知时(O(1)时间复杂度)。不支持随机访问:与std::vector不同,std::list不支持通过索引直接访问元素(不能通过list[i]的方式访问)。如果要访问某个元素,通常需要使用迭代器来逐个遍历,效率为O(n)。

二、list的使用

list的构造

在这里插入图片描述

在这里插入图片描述
构造的list中包含n个值为val的元素

list<int> l1(5, 1);

在这里插入图片描述
构造空的list

list<int> l2;

在这里插入图片描述
拷贝构造函数

list<int> l3(5,3);list<int> l4(l3);paint_list(l4);

在这里插入图片描述
用(first,list)区间的元素构造list

vector<int> v4{ 1,2,3,4,5 };list<int> l4(v4.begin(), v4.end());paint_list(l4);

在这里插入图片描述

list的迭代器使用

在这里插入图片描述
在这里插入图片描述
begin和end返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器

rbegin和rend,rbegin是容器里的最后一个元素,rend是容器里的第一个元素。相当于begin+end迭代器反了过来。

list<int> l5{ 1,2,3,4,5 };list<int> l6(l5.begin(), l5.end());list<int> l7(l5.rbegin(), l5.rend());paint_list(l6);paint_list(l7);

在这里插入图片描述

list的空间问题

在这里插入图片描述
在这里插入图片描述
判空

list<int> l6(5, 6);list<int> l7;cout<<l6.empty()<<endl;cout<<l7.empty()<<endl;

在这里插入图片描述
返回list中有效节点

list<int> l7(5, 7);cout << l7.size() << endl;

在这里插入图片描述

list的元素访问

在这里插入图片描述
在这里插入图片描述
返回第一个节点中值的引用
返回list的最后一个节点中值的引用

list<int> l8{ 1,2,3,4,5 };cout << l8.front() << endl;cout << l8.back() << endl;

在这里插入图片描述

list的插入与删除

在这里插入图片描述
在这里插入图片描述
在list首元素前插入值为val的元素

list<int> l9(5, 9);l9.push_front(1);paint_list(l9);

在这里插入图片描述
删除list中的第一元素

list<int> l10{ 1,2,3,4,5 };l10.pop_front();paint_list(l10);

在这里插入图片描述
在list尾部插入值为val的元素

list<int> l11{ 1,2,3,4,5 };l11.push_back(6);paint_list(l11);

在这里插入图片描述
删除list中最后一个元素

list<int> l12{ 1,2,3,4,5 };l12.pop_back();paint_list(l12);

在这里插入图片描述
在pop位置插入值为val的元素

list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);for (auto e : lt){cout << e << " ";}cout << endl;auto it = lt.begin();int k = 3;while (k--){++it;}lt.insert(it, 30);for (auto e : lt){cout << e << " ";}cout << endl;

在这里插入图片描述
删除pos位置的元素

list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);for (auto e : lt){cout << e << " ";}cout << endl;auto it = lt.begin();int k = 3;while (k--){++it;}lt.erase(it);for (auto e : lt){cout << e << " ";}cout << endl;

在这里插入图片描述
交换两个list中的元素

list<int> l15(15, 7);list<int> l16(15, 8);paint_list(l15);paint_list(l16);swap(l15, l16);paint_list(l15);paint_list(l16);

在这里插入图片描述
清理list中的有效元素

list<int> l16(15, 7);paint_list(l16);l16.clear();paint_list(l16);

在这里插入图片描述

迭代器失效问题

此处大家可将迭代器暂时理解成类似于指针, 迭代器失效即迭代器所指向的节点的无 效,即该节点被删除了 。因为 list 的底层结构为带头结点的双向循环链表 ,因此 在 list 中进行插入 时是不会导致 list 的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭 代器,其他迭代器不会受到影响 。

void TestListIterator1 (){int array [] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 };list < int > l ( array , array + sizeof ( array ) / sizeof ( array [ 0 ]));auto it = l . begin ();while ( it != l . end ()){// erase() 函数执行后, it 所指向的节点已被删除,因此 it 无效,在下一次使用 it 时,必须先给其赋值l . erase ( it );++ it ;}}// 改正void TestListIterator (){int array [] = { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 0 };list < int > l ( array , array + sizeof ( array ) / sizeof ( array [ 0 ]));auto it = l . begin ();while ( it != l . end ()){l . erase ( it ++ ); // it = l.erase(it);}}  

list和vector对比

在这里插入图片描述


点击全文阅读


本文链接:http://zhangshiyu.com/post/161163.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1