[C++初阶]list类的初步理解

一、标准库的list类

list的底层是一个带哨兵位的双向循环链表结构
对比forward_list的单链表结构,list的迭代器是一个双向迭代器
与vector等顺序结构的容器相比,list在任意位置进行插入删除的效率更好,但是不支持任意位置的随机访问
list是一个模板类,在使用的时候我们需要给出元素的类型

使用list类时,需要包含头文件<list>

二、list类的常用接口

1.常用的构造函数

1.默认构造函数,构造一个空的链表

list();

例如:

void test()
{list<int> lt;
}

2.构造一个list对象并用n个val初始化

list(size_type n, const value_type& val =  value_type());

例如:

void test()
{list<int> lt(3, 1);for (auto i : lt){cout << i << " ";}
}

运行结果:

3.list类的拷贝构造函数

list(const list& x); 

例如:

void test()
{list<int> lt(3, 1);list<int> lt1(lt);for (auto i : lt1){cout << i << " ";}
}

运行结果:

4.使用迭代器的初始化构造

Template<class InputIterator>list(InputIterator first, InputIterator last);

例如:

void test()
{list<int> lt(3, 1);list<int> lt1(lt.begin(), lt.end());for (auto i : lt1){cout << i << " ";}
}

运行结果:

2.常用的容量接口

还是老几样,我这里一块讲一讲吧。

1.size,empty,max_size,resize

size:返回链表容器中的元素数。

size_type size() const;

empty:返回列表容器是否为空(即其大小是否为 0)。
(注意:此函数不会以任何方式修改容器。若要清除链表容器的内容,请参阅 list::clear。)

bool empty() const;

max_size(不常用):返回链表容器可以容纳的最大元素数。
(由于已知的系统或库实现限制,这是容器可以达到的最大潜在大小,但绝不能保证容器能够达到该大小:在达到该大小之前,它仍然可能无法在任何时候分配存储。)

size_type max_size() const;

resize:调整容器的大小,使其包含 n 个元素。
如果 n 小于当前容器大小,则内容将减少到其前 n 个元素,删除超出(并销毁它们)的元素。
如果 n 大于当前容器大小,则通过在末尾插入所需数量的元素来扩展内容,以达到 n 的大小。如果指定了 val,则新元素将初始化为 val 的副本,否则,它们将进行值初始化。
(请注意,此函数通过插入或擦除容器中的元素来更改容器的实际内容。)

void resize (size_type n, value_type val = value_type());

例如:

​
void test()
{list<int> lt(3, 1);/*list<int> lt1(lt);*/list<int> lt1(lt.begin(), lt.end());list<int> lt2;cout << lt1.size() <<endl;cout << lt1.empty() <<endl;cout << lt2.empty() <<endl;lt1.resize(10);cout << lt1.size() << endl;for (auto i : lt1){cout << i << " ";}
}​

运行结果:

3. 常用的访问与遍历

1.迭代器

iterator begin();const_iterator begin() const;iterator end();const_iterator end() const;

迭代器:用于获取链表中第一个节点的位置和最后一个节点的下一个位置(即哨兵位)

例如:

void test()
{list<int> lt(5, 2);list<int> ::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}
}

运行结果:

2.反向迭代器

reverse_iterator rbegin();

const_reverse_iterator rbegin() const;

reverse_iterator rend();

const_reverse_iterator rend() const;

反向迭代器,rbegin获取容器中最后一个节点的位置,rend获取容器中哨兵位的位置

void test()
{list<int> lt = { 1,23,4,4,5,2 };list<int> ::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}
}

运行结果:

注意:反向迭代器rit也要用++而不是--

3.front和back

front:

reference front();

const_reference front() const;

返回链表中第一个节点存储的数据的引用

back:

reference back();

const_reference back() const;

返回链表中最后一个节点存储的数据的引用

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.front() << endl;cout << lt.back() << endl;}

运行结果:

4.list的增删查改

1)push_front和pop_front

push_front叫头插,从链表头部插入一个元素

void push_front(const value_type& val);

pop_front叫头删,从链表头部删除一个元素

void pop_front();

void pop_front();

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.front() << endl;lt.push_front(21345);cout << lt.front() << endl;lt.pop_front();cout << lt.front() << endl;
}

运行结果:

2) push_back和pop_back

push_back叫尾插,从链表尾部插入一个元素

void push_back(const value_type& val);

pop_back叫尾删,从链表尾部删除一个元素

void pop_back();

例如:

void test()
{list<int> lt = {213123,123,34524,213};cout << lt.back() << endl;lt.push_back(21345);cout << lt.back() << endl;lt.pop_back();cout << lt.back() << endl;
}

运行结果:

3) find

template <class InputIterator, class T>InputIterator find(InputIterator first, InputIterator last, const T& val);

在两个迭代器区间寻找val并返回其所在处的迭代器

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);*pos = 114514;for (auto i : lt){cout << i << " ";}
}

运行结果:

注意:该函数并非list的成员函数,是标准库中的函数,多个容器共用该find函数

可以看到,我们可以直接对list的迭代器进行解引用并修改其内容,但是迭代器不应该指向节点吗?为什么对其解引用能修改数据呢?

实际上list的迭代器并不是用原生态指针进行模拟实现的,需要进行底层的封装,这里会在list的模拟实现的源代码中体现。

4)insert

iterator insert(iterator position, const value_type& val);

void insert(iterator position, size_type n, const value_type& val);

————————————————————————————————————————

template<class InputIterator>

void insert(iterator position, InputIterator first, InputIterator last);

在position位置的前面插入一个或多个元素

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);lt.insert(pos, 8848);for (auto i : lt){cout << i << " ";}
}

运行结果:

细心的同学可能已经发现了,list的insert操作是不会导致迭代器失效的,因为pos指向的节点不变,相对位置也不变。

但是list的删除操作一定会导致迭代器失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响。

5) erase

iterator erase(iterator position);iterator erase(iterator first, iterator last);

删除position位置的元素或者 [first,last) 区间的所有元素

例如:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 1);lt.erase(lt.begin());for (auto i : lt){cout << i << " ";}
}

运行结果:

void test()
{list<int> lt;for (int i = 0; i < 3; i++){lt.push_back(i);}list<int>::iterator pos = find(lt.begin(), lt.end(), 2);lt.erase(lt.begin(),pos);for (auto i : lt){cout << i << " ";}
}

运行结果:

6) swap

void swap(vector& x);

交换两个list对象

例如:

void test()
{list<int> lt;list<int> lt2(6, 12);for (int i = 0; i < 10; i++){lt.push_back(i);}lt.swap(lt2);for (auto i : lt2){cout << i << " ";}cout << endl;
}

运行结果:

7)assign

template <class InputIterator>

void assign(InputIterator first, InputIterator last);

void assign(size_type n, const value_type& val);

为list指定新内容,替换其当前内容并修改节点个数

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}lt.assign(4, 0);for (auto i : lt){cout << i << " ";}
}

运行结果:

8)clear

void clear();

删除链表所有节点

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}lt.clear();cout << lt.size() << endl;
}

运行结果:

5.list的顺序修改接口

(1)sort

void sort();

template<class Compare>

void sort(Compare comp);

list由于结构的特殊性,是无法使用标准库中的sort函数的,因为迭代器无法进行相减的操作

并且在C++文档中,我们可以看到标准库中的sort也限定了迭代器的类型必须是可以进行随机访问(RandomAccess)的

default (1)	
template <class RandomAccessIterator>void sort (RandomAccessIterator first, RandomAccessIterator last);
custom (2)	
template <class RandomAccessIterator, class Compare>void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

迭代器有几个功能分类:

  • 单向迭代器,只能进行++
  • 双向迭代器,可以++和--
  • 随机迭代器,可以++,--,+和-

但是list的sort函数也是没什么必要的,因为直接对链表排序的效率比拷贝到vector进行排序再拷贝回链表要慢的多。

(2)reverse

template <class BidirectionalIterator>void reverse (BidirectionalIterator first, BidirectionalIterator last);

对链表进行逆置

例如:

void test()
{list<int> lt;for (int i = 0; i < 10; i++){lt.push_back(i);}for (auto i : lt){cout << i << " ";}cout << endl;lt.reverse();for (auto i : lt){cout << i << " ";}cout << endl;}

运行结果:


如有错误,欢迎指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3226604.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

【EIScopus稳检索-高录用】第五届大数据与社会科学国际学术会议(ICBDSS 2024)

大会官网&#xff1a;www.icbdss.org 大会时间&#xff1a;2024年8月16-18日 大会地点&#xff1a;中国-上海 接受/拒稿通知&#xff1a;投稿后1-2周内 收录检索&#xff1a;EI,Scopus *所有参会者现场均可获取参会证明&#xff0c;会议通知&#xff08;邀请函&#xff09;&…

二维码生成需知:名片二维码尺寸多少合适?电子名片二维码制作方法?

随着数字化时代的到来&#xff0c;二维码在各个领域的应用越来越广泛&#xff0c;名片作为商业交流的重要工具之一&#xff0c;也开始逐渐融入二维码的元素。通过在名片上添加二维码&#xff0c;我们可以轻松实现信息的快速传递和分享。然而&#xff0c;名片二维码的尺寸选择成…

【割点 C++BFS】2556. 二进制矩阵中翻转最多一次使路径不连通

本文涉及知识点 割点 图论知识汇总 CBFS算法 LeetCode2556. 二进制矩阵中翻转最多一次使路径不连通 给你一个下标从 0 开始的 m x n 二进制 矩阵 grid 。你可以从一个格子 (row, col) 移动到格子 (row 1, col) 或者 (row, col 1) &#xff0c;前提是前往的格子值为 1 。如…

国产口碑最好的骨传导耳机有哪些?优选五大高口碑机型推荐!

作为一名有着多年工作经验的数码测评师&#xff0c;可以说对骨传导耳机或者蓝牙耳机等数码产品有着深入的了解&#xff0c;近期&#xff0c;有很多粉丝&#xff0c;或者身边的朋友经常向我咨询关于骨传导耳机的问题。确实如此&#xff0c;优质的骨传导耳机能在保护听力、保持环…

HKT DICT解决方案,为您量身打造全方位的一站式信息管理服务

随着大数据时代的到来&#xff0c;企业对现代化管理、数据整合与呈现的解决方案需求不断增长。为满足更多企业客户的多元化信息管理发展需求&#xff0c;香港电讯&#xff08;HKT&#xff09;强势推出全面、高效、安全、可靠的一站式DICT&#xff08;Digital Information and C…

【Python系列】深入解析 Python 中的 JSON 处理工具

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

IDEA常用技巧荟萃:精通开发利器的艺术

1 概述 在现代软件开发的快节奏环境中&#xff0c;掌握一款高效且功能全面的集成开发环境&#xff08;IDE&#xff09;是提升个人和团队生产力的关键。IntelliJ IDEA&#xff0c;作为Java开发者的首选工具之一&#xff0c;不仅提供了丰富的编码辅助功能&#xff0c;还拥有高度…

【NLP学习笔记】transformers中的tokenizer切词时是否返回token_type_ids

结论 先说结论&#xff1a; 是否返回token_type_ids&#xff0c;可以在切词时通过 return_token_type_idsTrue/False指定&#xff0c;指定了True就肯定会返回&#xff0c;指定False&#xff0c;不一定就不返回。 分析 Doc地址 https://huggingface.co/docs/transformers/main…

【电脑应用技巧】如何寻找电脑应用的安装包华为电脑、平板和手机资源交换共享

电脑的初学者可能会直接用【百度】搜索电脑应用程序的安装包&#xff0c;但是这样找到的电脑应用程序安装包经常会被加入木马或者强制捆绑一些不需要的应用装入电脑。 今天告诉大家一个得到干净电脑应用程序安装包的方法&#xff0c;就是用【联想的应用商店】。联想电脑我是一点…

看到指针就头疼?这篇文章让你对指针有更全面的了解!

文章目录 1.什么是指针2.指针和指针类型2.1 指针-整数2.2 指针的解引用 3.野指针3.1为什么会有野指针3.2 如何规避野指针 4.指针运算4.1 指针-整数4.2 指针减指针4.3 指针的关系运算 5.指针与数组6.二级指针7.指针数组 1.什么是指针 指针的两个要点 1.指针是内存中的一个最小单…

智能雷达AI小程序源码系统 销售名片+企业商城+公司动态 带完整的安装代码包以及搭建教程

系统概述 智能雷达AI小程序源码系统是基于先进的AI技术和小程序框架开发的全能型企业级应用。它不仅整合了个人销售名片的便捷分享&#xff0c;还融入了功能丰富的企业商城和实时更新的公司动态展示&#xff0c;实现了从品牌形象塑造到产品销售&#xff0c;再到客户关系维护的…

TransIT-VirusGEN® Transfection Reagent

Mirus转染试剂TransIT-VirusGEN Transfection Reagent&#xff0c;该产品旨在增强载体转染到 贴壁或悬浮的HEK 293细胞的转染效率&#xff0c;并增加重组腺相关病毒或慢病毒的产量。 使用TransIT-VirusGEN转染试剂转染悬浮或贴壁HEK293细胞可获得最高的转染效率。使用不同的转…

【Flask从入门到精通:第一课:flask的基本介绍、flask快速搭建项目并运行】

从0开始入手到上手一个新的框架&#xff0c;应该怎么展开&#xff1f;flask这种轻量级的框架与django这种的重量级框架的区别&#xff1f;针对web开发过程中&#xff0c;常见的数据库ORM的操作。跟着学习flask的过程中&#xff0c;自己去学习和了解一个新的框架&#xff08;San…

常见的过压保护芯片、过压保护的基本参数和选型

过压保护也叫过电压保护&#xff0c;是当电压超过预定的最大值时&#xff0c;使电源断开或使受控设备电压降低的一种保护方式。 过压保护芯片是为了防止输入电压的时候浪涌和波纹过大&#xff0c;导致烧坏后面的元器件芯片。因此过压保护芯片是很有必要的芯片。 常见的过压保护…

经验分享:征信查询多了会不会影响大数据综合评分?

很多人在申请贷款的时候&#xff0c;会有一个疑问&#xff0c;就是自己的征信没逾期&#xff0c;就是查询偏多一点&#xff0c;但能达到申贷要求&#xff0c;为什么还会被拒贷?其实就是大数据花了的原因&#xff0c;那征信查询多了会不会影响大数据综合评分呢?接下来本文就为…

AI自动生成PPT哪个软件好?揭秘5款自动生成PPT的工具

在职场的竞技场上&#xff0c;演示文稿如同战士的利剑&#xff0c;其锋芒直接影响着演讲者的说服力。 然而&#xff0c;制作一份高质量的PPT往往需要耗费大量时间与精力。随着科技的进步&#xff0c;AI自动生成PPT成为了提升效率的新选择。面对市场上琳琅满目的软件&#xff0…

如何给ubuntu虚拟机扩容

虚拟机设置 鼠标点击硬盘&#xff0c;弹出对话框后&#xff0c;点击扩展&#xff0c;输入扩展后的硬盘大小&#xff0c;我这里扩展到100G 安装工具 sudo apt-get install gparted 重新分区

今天,纷享AI正式发布,开启智能CRM新纪元

纷享销客作为国产CRM中连续四年保持近40%增长的领先品牌&#xff0c;一直在探索AICRM领域的数字化变革。 7月10日&#xff0c;纷享AI产品正式上线。与通用大模型不同&#xff0c;纷享AI是在合规之下&#xff0c;开放性的接入各种大模型平台&#xff0c;并结合纷享销客在营销服…

如何学习一门新技术,十年 MarkDown 程序员怎么做

案例源码仓库地址&#xff1a; https://github.com/Rodert/go-demo官方文档&#xff1a; https://etcd.io/视频教程&#xff1a; https://space.bilibili.com/404747369 文章目录 介绍使用场景 安装&搭建搭建 ETCD与 ETCD 交互集群 GoETCD 编码 介绍 谈使用场景之前&#…

【IEEE官方列表会议,EI, Scopus稳定检索】第三届半导体与电子技术国际研讨会(ISSET 2024,2024年8月23-25)

2024年第三届半导体与电子技术国际研讨会&#xff08;ISSET 2024&#xff09;将于2024年8月23-25日在中国西安举行。 ISSET 2024将围绕“半导体”与“电子技术”等相关最新研究领域&#xff0c;为来自国内外高等院校、科学研究所、企事业单位的专家、教授、学者、工程师等提供一…