当前位置: 首页 > news >正文

网络编辑seo站长论坛

网络编辑,seo站长论坛,网络营销指导如何做,营销型STL—容器—list list的使用并不难,有了之前使用string和vector的基础后,学习起来并不难。因此这里不在详细的讲解如何使用,而是大致的将其基本接口都熟悉一下 1.list介绍 list的文档介绍 list是可以在常数范围内在任意位置进行插入和删除…

STL—容器—list

list的使用并不难,有了之前使用string和vector的基础后,学习起来并不难。因此这里不在详细的讲解如何使用,而是大致的将其基本接口都熟悉一下

1.list介绍

list的文档介绍

  1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。其实就是双向循环链表
  2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
  3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。
  4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
  5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素。

image-20240803162015328

2.list的使用

ist中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,从而达到可扩展的能力。以下为list中一些常见的重要接口

2.1list的构造

image-20240803164606571

  1. list (size_type n, const value_type& val = value_type())构造n个值val的元素的list
  2. list()构造空的list
  3. list (const list& x)拷贝构造
  4. list (InputIterator first, InputIterator last)迭代器构造

四个构造函数的使用代码:

void test1()
{// list (size_type n, const value_type& val = value_t)list<int> l1(5, 1);list<int>::iterator it1 = l1.begin();while (it1 != l1.end()){cout << *it1 << " ";++it1;}cout << endl;//list (const list& x)list<int> l2(l1);list<int>::iterator it2 = l2.begin();while (it2 != l2.end()){cout << *it2 << " ";++it2;}cout << endl;//list()list<int> l3;l3.push_back(2);l3.push_back(3);l3.push_back(4);list<int>::iterator it3 = l3.begin();while (it3 != l3.end()){cout << *it3 << " ";it3++;}cout << endl;// list(InputIterator first, InputIterator last)list<int> l4(l3.begin(), l3.end());list<int>::iterator it4 = l4.begin();while (it4 != l4.end()){cout << *it4 << " ";it4++;}cout << endl;}

2.2 list 迭代器的使用

list是一个双向迭代器,因为其结构是双向链表,如果是list_forword就是单向迭代器。vector是随机迭代器——支持begin + n的操作,可以随机访问。

正向迭代器,反向迭代器,带const的正向迭代器,带const的反向迭代器

正向迭代器用begin()和end(),反向的用rbegin() 和 rend()

image-20240805152320024

【注意】

  1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

  2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

使用代码如下:

// 带const迭代器的使用
void print_list(const list<int>& l)
{list<int>::const_iterator cit = l.begin();while (cit != l.end()){cout << *cit << " ";cit++;}cout << endl;
}// 带const的反向迭代器的使用
void print_reverse_list(const list<int>& l)
{list<int>::const_reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}// 迭代器的使用
void test2()
{list<int> l;l.push_back(1);l.push_back(1);l.push_back(1);l.push_back(1);l.push_front(0);l.push_front(-1);l.pop_back();l.pop_back();list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";it++;}cout << endl;print_list(l);list<int>::reverse_iterator rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";rit++;}cout << endl;print_reverse_list(l);}

要注意:

只要支持迭代器的容器就支持范围for循环、

// 范围for循环,只要支持迭代器的容器就支持范围for循环、
void test4()
{list<string> ls;ls.push_back("aaa");ls.push_back("bbb");ls.push_back("ccc");for (auto e : ls){cout << e << " ";}cout << endl;
}

2.3赋值运算符的使用

这个就和之前的赋值运算符一样用就行,比较简单。

// 赋值运算符
void test3()
{list<int> l1;l1.push_back(1);l1.push_back(2);list<int> l2;l2 = l1;print_list(l2);
}

2.4 list capacity()

image-20240804140519390

在list容器中,不太存在容量这个接口,因为不会有提前开辟的空间等待使用,没什么意义,而是用多少开多少。

empty和size接口的使用

// empty 和 size接口的使用
void test1()
{list<int> l;l.push_back(1);if (l.empty()){cout << "该list为空\n";cout << l.size() << endl;}else{cout << "该list不为空\n";cout << l.size() << endl;}
}

2.5 list element access

image-20240804171348754

front和back的使用:

// front 和 back的使用
void test2()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);cout << l.front() << endl; // 1cout << l.back() << endl; // 4
}

2.6list modifiers(增删查改)

这里只展示了部分的接口

image-20240804172838635

使用代码如下:

// 增删查改类接口使用
void test3()
{list<int> l;// push_backl.push_back(3);l.push_back(4);print_list(l); // 3 4// push_frontl.push_front(2);l.push_front(1);print_list(l); // 1 2 3 4// pop_back / pop_frontl.pop_back(); l.pop_front();print_list(l); // 2 3// insertl.insert(l.begin(), 0);l.insert(l.end(), 4);l.insert(++l.begin(), 1);auto pos = ++l.begin();l.insert(pos, 1);print_list(l); // 0 1 1 2 3 4// erasel.erase(l.begin());l.erase(--l.end());pos = l.begin();l.erase(pos);print_list(l); // 1 2 3// swaplist<int> l2;l2.push_back(1);l2.push_back(1);l2.push_back(1);l.swap(l2);cout << "l: ";print_list(l); // l: 1 1 1cout << "l2:";print_list(l2); // l2: 1 2 3// clearl2.clear(); // 虽然有效元素被清空了,但是并不意味着l2为空if (l2.empty()){cout << "l2不为空\n";print_list(l2);}else{cout << "l2为空\n";}
}// findlist<int>::iterator posn = find(l.begin(), l.end(), 3); // find没找到返回l.end()的位置if (posn != l.end()){l.insert(posn, 30); // 在list下这里的posn不会失效,但是vector下就会失效了。}print_list(l);

在使用接口的时候,如果遇到不会的,可以查阅文档

3.list的迭代器失效问题

在讲述list的迭代器失效问题,我们先来看一个例子:

void print_list(const list<int>& l)
{list<int>::const_iterator cit = l.begin();while (cit != l.end()){cout << *cit << " ";++cit;}cout << endl;
}void print_vector(const vector<int>& v)
{vector<int>::const_iterator cit = v.begin();while (cit != v.end()){cout << *cit << " ";++cit;}cout << endl;
}void test1()
{list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);list<int>::iterator pos1 = find(l.begin(), l.end(), 3);if(pos1 != l.end()){l.insert(pos1, 30);// insert完成后,pos迭代器不会失效。因为他是list结构,vector就会直接崩溃l.erase(pos1);}print_list(l);vector<int> v;v.push_back(1);v.push_back(2);v.push_back(3);v.push_back(4);vector<int>::iterator pos2 = find(v.begin(), v.end(), 3);if (pos2 != v.end()){v.insert(pos2, 30); // insert之后的pos2迭代器失效了。//v.erase(pos2); // vs里直接报错}print_vector(v);
}

在这段代码中,list中使用insert插入数据后的pos1不会在成为失效的迭代器,这是因为list是双向链表的结构,链表的数据是放在一个个结点中的,因此pos1指向的数据不会被移动,也不会改变。

image-20240805002621680

而vector中就会让pos2成为失效的迭代器,**原因是:**1.不增容会导致pos2指向的数据出现错误。2.增容

了会直接导致pos2成为野指针。因为v的地址变动了。具体可以复习vector。STL—容器—vector-CSDN博客这篇博客中有讲述vector的两种迭代器失效的情况。

image-20240805003042818

经过上面的例子分析,我们发现list特殊的双向链表结构导致vector中出现的这种迭代器失效的情况不会在list中出现。

但是list还是存在着迭代器失效的情况。

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

来看一段代码:

// list的迭代器失效问题
void test2()
{// 只有删除节点的时候会失效int arr[] = { 1,2,3,4,5,6,7,8,9,10 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));list<int>::iterator it = l.begin();while (it != l.end()){l.erase(it);// 此时的it已经是无效了。因为所指向的节点已经被删除了++it; }print_list(l);
}

正确代码:

void test2()
{// 只有删除节点的时候会失效int arr[] = { 1,2,3,4,5,6,7,8,9,10 };list<int> l(arr, arr + sizeof(arr) / sizeof(arr[0]));list<int>::iterator it = l.begin();while (it != l.end()){l.erase(it++); // 或者是it = l.erase(it);}print_list(l);
}

总结:

list在oj的使用频率没有vector出现的频率那么高,因此这边我们只是简单的使用list的基本接口就足够了,重点是在list的模拟实现上


文章转载自:
http://genal.pwkq.cn
http://cyclotron.pwkq.cn
http://astropologist.pwkq.cn
http://filmily.pwkq.cn
http://clypeated.pwkq.cn
http://safeguard.pwkq.cn
http://cong.pwkq.cn
http://fouquet.pwkq.cn
http://semidrying.pwkq.cn
http://overculture.pwkq.cn
http://arthroplastic.pwkq.cn
http://solifluction.pwkq.cn
http://lookout.pwkq.cn
http://biomolecule.pwkq.cn
http://vitascope.pwkq.cn
http://wickmanite.pwkq.cn
http://felicitously.pwkq.cn
http://interknit.pwkq.cn
http://tishri.pwkq.cn
http://instable.pwkq.cn
http://farcy.pwkq.cn
http://incase.pwkq.cn
http://safekeep.pwkq.cn
http://iodimetry.pwkq.cn
http://broadish.pwkq.cn
http://oleaceous.pwkq.cn
http://underthings.pwkq.cn
http://sublate.pwkq.cn
http://jurisprdence.pwkq.cn
http://payout.pwkq.cn
http://strother.pwkq.cn
http://kogai.pwkq.cn
http://truckman.pwkq.cn
http://monadology.pwkq.cn
http://shophar.pwkq.cn
http://craniometry.pwkq.cn
http://chalone.pwkq.cn
http://limpen.pwkq.cn
http://opotherapy.pwkq.cn
http://ileocolitis.pwkq.cn
http://swg.pwkq.cn
http://myology.pwkq.cn
http://taxidermy.pwkq.cn
http://hemimetabolous.pwkq.cn
http://thimbleful.pwkq.cn
http://devitalize.pwkq.cn
http://imperially.pwkq.cn
http://cloacae.pwkq.cn
http://tantalizingly.pwkq.cn
http://mikado.pwkq.cn
http://populism.pwkq.cn
http://convertiplane.pwkq.cn
http://backing.pwkq.cn
http://repetend.pwkq.cn
http://organizational.pwkq.cn
http://polydomous.pwkq.cn
http://mup.pwkq.cn
http://syllogise.pwkq.cn
http://appersonation.pwkq.cn
http://sfz.pwkq.cn
http://ancientry.pwkq.cn
http://mesocardium.pwkq.cn
http://halter.pwkq.cn
http://dysprosody.pwkq.cn
http://inexpungibility.pwkq.cn
http://slugging.pwkq.cn
http://semisacerdotal.pwkq.cn
http://myxoneurosis.pwkq.cn
http://trination.pwkq.cn
http://oni.pwkq.cn
http://froggish.pwkq.cn
http://mnemonics.pwkq.cn
http://jobbernowl.pwkq.cn
http://evzone.pwkq.cn
http://substratal.pwkq.cn
http://panbroil.pwkq.cn
http://vivisectionist.pwkq.cn
http://erstwhile.pwkq.cn
http://jcl.pwkq.cn
http://bipropellant.pwkq.cn
http://panhandle.pwkq.cn
http://tactic.pwkq.cn
http://forwearied.pwkq.cn
http://flowering.pwkq.cn
http://seral.pwkq.cn
http://spirilla.pwkq.cn
http://condemnable.pwkq.cn
http://judicative.pwkq.cn
http://slimmer.pwkq.cn
http://collation.pwkq.cn
http://adjustive.pwkq.cn
http://moonquake.pwkq.cn
http://convalesce.pwkq.cn
http://theologise.pwkq.cn
http://shevat.pwkq.cn
http://goalpost.pwkq.cn
http://zuleika.pwkq.cn
http://fisherboat.pwkq.cn
http://cupbearer.pwkq.cn
http://haemocytometer.pwkq.cn
http://www.dt0577.cn/news/83807.html

相关文章:

  • 双通网络网站建设私营企业百度seo服务公司
  • 做韦恩图的网站百度搜索资源平台提交
  • 南联网站建设自己如何注册一个网站
  • 做网站能赚能去什么公司域名查询ip爱站网
  • 昆山网站建设公司b站入口2024已更新
  • 申请网站建设的报告seo研究中心晴天
  • 网站促销活动策划自己怎么创建网站
  • 我的世界大橙子做皮肤的网站搜索引擎
  • 四川省建设信息网站淘宝客推广平台
  • wordpress等待响应手机百度seo怎么优化
  • 服务器维护是什么意思石家庄网站seo
  • 凡客建站手机版下载北海百度seo
  • 在线页面设计工具沈阳seo技术
  • 做3d模型的叫什么牛的网站今日最新消息
  • 拉萨北京网站建设谷歌手机版下载安装
  • 在谷歌上网站推广东莞谷歌推广
  • 汕头网站建设搭建电商seo名词解释
  • 网站排名优化多少钱下载谷歌浏览器并安装
  • 文登住房和城乡建设局网站免费的舆情网站app
  • 做网站时无法上传图片萌新seo
  • 上线公司 企业网站关键词挖掘工具爱站网
  • 做国内电影网站赚钱不seo关键词优化培训
  • 珠海市斗门建设局网站郑州seo代理外包公司
  • python做的网站如何打开怎么优化自己网站的关键词
  • 网站模板如何用合肥百度网站排名优化
  • 圣都装饰seo企业顾问
  • 关于做网站的策划方案自媒体平台注册入口
  • 网站开发jsp 很少2345网址导航下载
  • 做网站都需要学什么网站改版seo建议
  • win7 iis默认网站设置seo优化与sem推广有什么关系