🔥个人主页🔥:孤寂大仙V
🌈收录专栏🌈:C++从小白到高手
🌹往期回顾🌹:[C++]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 的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭 代器,其他迭代器不会受到影响 。
voidTestListIterator1(){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 ;}}// 改正voidTestListIterator(){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对比
版权归原作者 孤寂大仙v 所有, 如有侵权,请联系我们删除。