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

深圳移动网站建设站长之家怎么用

深圳移动网站建设,站长之家怎么用,100个顺口的公司名字,电影网站是怎么做的目录 为什么会有list? 迭代器失效: list和vector的迭代器不同的地方: list的大部分用法和vector都很像,例如push_back,构造,析构,赋值重载这些就不再废话了,本篇主要讲的是和vecto…

目录

为什么会有list?

迭代器失效:

 list和vector的迭代器不同的地方:


list的大部分用法和vector都很像,例如push_back,构造,析构,赋值重载这些就不再废话了,本篇主要讲的是和vector不同的点

构造、拷贝构造:

析构:

赋值重载:

尾插:

为什么会有list?

vector就可以存储多个数据了,为什么还要有一个list呢?相信这是很多初学者的问题之一,下面就给大家说清楚

vector缺点:

  1. 头部和中部的插入删除效率低(O(N)),因为需要挪动数据
  2. 插入数据空间不够需要增容,增容需要开新空间、拷贝数据、释放旧空间,会付出很大的代价

vector优点:

支持下标的随机访问,间接的就很好的支持排序、二分查找、堆算法等等

通过上面可知,vector因为支持下标的随机访问(即空间是连续的),那么再增删查改就会牺牲效率

为了解决这个痛点,就有了list

vector插入数据需要先将后面的数据往后移,如图所示

而list只需要再开辟一个新节点,并将其左右连接起来就进可以,如图所示

 但虽然list解决了vector的痛点,也同时失去了vector的优点,即随机访问

list缺点:

不支持随机访问

list优点:

  1. list头部、中部插入数据不再需要挪动数据,效率高(O(1))
  2. list插入数据是新增节点,不需要增容

所以在实际使用中vector和list是相辅相成的两个容器

 和string,vector一样,list也有迭代器,用法也一样,但string和vector在遍历数据时有三种方法,分别是[]+for、迭代器、范围for,但list中没有[]+for这个方法了,因为[]重载的前提是容器本身支持随机访问,而list不支持随机访问,自然没有[]重载

迭代器遍历:

list<int> lt;
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_front(1);//list中不仅支持尾插和尾删,还支持头插和头删list<int>::iterator it = lt.begin();
while (it != lt.end())
{cout << *it << " ";it++;
}

(list中不仅支持vector已有的尾插和尾删,还支持头插和头删) 

范围for遍历:(只要支持迭代器,就支持范围for)

list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);for(auto e : lt)
{cout << e << " ";
}

从支持的操作接口的角度分迭代器的类型:单向(forword_list)、双向(list)、随机(vector)

迭代器失效:

那下面的代码是否可以运行呢?

int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while(it != lt.end()){if(*it % 2 == 0)lt.erase(it);it++;}return 0;
}

 这段程序的目的是删除链表中的偶数,但如果运行的话会报错

 原因和vector的迭代器失效类似,但上述代码list迭代器失效主要是因为都删除了这个节点了,那现在这个迭代器里指向的是一个被释放的空间,那当然不行

改也和vector的改法一样

int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while (it != lt.end()){if (*it % 2 == 0)it = lt.erase(it);elseit++;//把it++放在else里是因为如果执行了erase,它的返回值就是删除的元素的下一个元素的迭代器}return 0;
}

那这段代码会发生迭代器失效吗?

int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = lt.begin();while (it != lt.end()){if (*it % 2 == 0)lt.insert(it, 114);it++;}return 0;
}

答案是不会

怎么insert又不会迭代器失效了?

在vector中,insert会迭代器失效是因为原本指向这个数据的迭代器在插入数据后不是指向那个数了

而在list中,插入数据并不会改变迭代器的指向,insert后迭代器还是指向原来的数据

所以在list中,insert不会迭代器失效,erase会迭代器失效

那在vector中,插入使得扩容也会迭代器失效,list会吗?

 关于capacity的接口就只有这3个,可以看到,只有size,没有capacity,因为list不存在扩容的问题,每次插入数据都会新开辟一块空间,所以list不需要扩容,自然也不会因为扩容而迭代器失效

注:迭代器失效了没什么事,是去访问失效的迭代器就会出现问题

list还支持调出头尾数据(vector也支持)

list<int> lt;
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(5);
lt.push_front(1);//list中不仅支持尾插和尾删,还支持头插和头删
cout << lt.front() << endl;
cout << lt.back() << endl;

输出结果:

 list还支持翻转接口

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";
}int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.reverse();print(lt);return 0;
}

 输出结果:

 list还支持排序,是的你没看错,连vector都没有内置的sort函数,list竟然有(不过效率很低,不常用)

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";
}int main()
{list<int> lt;lt.push_back(4);lt.push_back(2);lt.push_back(7);lt.push_back(1);lt.push_back(4);lt.sort();print(lt);return 0;
}

输出结果:

 list和vector的迭代器不同的地方:

 如果想在第三个位置的前方加入一个数据

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";
}int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.insert(lt.begin() + 2, 114);print(lt);return 0;
}

这样写可以吗?

如果是在vector的话,没问题,但list就会报错

vector支持随机访问,所以begin() + 2这种操作就是往后移两位。

但list不支持随机访问,begin() + 2 就加到未知的空间去了所以会报错

正确写法是这样 

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";
}int main()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);list<int>::iterator it = find(lt.begin(), lt.end(), 3);lt.insert(it, 114);print(lt);return 0;
}

需要用到全局的算法接口find,找到begin()到end()范围(左闭右开区间)内第一个值是3的地方(从左往右走),返回值就是这个地方的迭代器

list还支持转移

它支持将链表的全部或者某一个区域的数据转移到另一个链表中

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";cout << endl;
}int main()
{list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);lt1.push_back(5);list<int> lt2;lt2.push_back(114);lt2.push_back(514);lt2.push_back(191);lt1.splice(lt1.begin(), lt2);//将lt2的数据全部移动到lt1开始的位置print(lt1);print(lt2);//此时lt2就是空了因为都被移走了return 0;
}

输出结果:

第二行为空是因为lt2的数据都转移到lt1了 

remove接口也是删除一个数(用得不多)

void print(const list<int>& lt)
{for (const auto& e : lt)cout << e << " ";cout << endl;
}int main()
{list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);lt1.push_back(5);lt1.remove(2);//从左往右开始找值为2的数据并删掉print(lt1);return 0;
}

 但它是找AND删,而erase是删除指定的迭代器的位置

http://www.dtcms.com/wzjs/207687.html

相关文章:

  • 如何在自己建设的网站上发表文章成都排名seo公司
  • 网站建设公司推广网站品牌运营百度爱采购
  • 湛江网站建设服务sem优化技巧
  • 广东网站建设模板衡阳seo优化报价
  • 号店网站建设公司网络销售是做什么的
  • 网站商城定制网站建设博客营销案例
  • 少儿编程培训机构哪家好青岛网站建设方案优化
  • 做动态网站的软件有哪些内容企拓客app骗局
  • 做软件好还是做网站好专业做seo推广
  • wordpress登陆页厦门关键词排名seo
  • 网站做聚合页面站长网站优化公司
  • 深圳 网站建设培训网站推广软文
  • 南宁外贸网站建设国际新闻网站
  • 网站收录降低冯耀宗seo博客
  • 自己如何建设个网站免费找客户软件
  • 我的世界怎么自己做皮肤并上传网站百度帐号
  • 一般公路建设招投标在什么网站上网站换了域名怎么查
  • 武汉阳网站建设平台营销渠道策划方案
  • 百度云如何建设网站nba最新排名榜
  • 哪个网站做网店好台州关键词优化服务
  • 网站经营许可备案自己做一个网站
  • 房地产管理局网站南宁seo外包服务商
  • 湖南广厦建设工程有限公司网站青岛百度关键词优化
  • 临沂做网站哪里好网站推广途径和要点
  • 呼市网站seo优化工资提成怎么算搜索引擎营销优化的方法
  • 大兴做网站的公司百度平台app下载
  • 网络代理网站好口碑关键词优化
  • 广告设计软件叫什么北京专业网站优化
  • 怎样建设微网站网站推广的基本方法
  • 岳阳仲裁委员会网站建设新增2022网站seo