C++STL:顺序容器之forward_list

news2024/12/27 12:25:23

文章目录

  • 1. 概述
  • 2. 成员函数
    • 和使用forward_list容器相关的函数
  • 3. forward_list 容器的创建

1. 概述

forward_list 是 C++ 11 新添加的一类容器,其底层实现和 list 容器一样,采用的也是链表结构,只不过 forward_list 使用的是单链表,而 list 使用的是双向链表。 如下图所示:

在这里插入图片描述

上图中,H 表示链表的表头。a) 表示单链表,b) 表示双向链表。不难看出,使用链表存储数据最大的特点在于,其并不会将数据进行集中存储(向数组那样),换句话说,链表中数据的存储位置是分散的、随机的,整个链表中数据的线性关系通过指针来维持。因此,forward_list 容器具有和 list 容器相同的特性,即擅长在序列的任何位置进行插入元素或删除元素的操作,但对于访问存储的元素,没有其它容器(如 array、vector)的效率高。

另外,由于单链表没有双向链表那样灵活,因此相比 list 容器,forward_list 容器的功能受到了很多限制。比如,由于单链表只能从前向后遍历,而不支持反向遍历,因此 forward_list 容器只提供前向迭代器,而不是双向迭代器。这意味着,forward_list 容器不具有 rbegin()、rend() 之类的成员函数。

那么,既然 forward_list 容器具有和 list 容器相同的特性,list 容器还可以提供更多的功能函数,forward_list 容器有什么存在的必要呢?当然有,forward_list 容器底层使用单链表,也不是一无是处。比如,存储相同个数的同类型元素,单链表耗用的内存空间更少,空间利用率更高,并且对于实现某些操作单链表的执行效率也更高。

效率高是选用 forward_list 而弃用 list 容器最主要的原因,换句话说,只要是 list 容器和 forward_list 容器都能实现的操作,应优先选择 forward_list 容器。

2. 成员函数

成员函数功能
before_begin()返回一个前向迭代器,其指向容器中第一个元素之前的位置。
begin()返回一个前向迭代器,其指向容器中第一个元素的位置。
end()返回一个前向迭代器,其指向容器中最后一个元素之后的位置。
cbefore_begin()和 before_begin() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素。
cbegin()和 begin() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素。
cend()和 end() 功能相同,只不过在其基础上增加了 const 属性,不能用于修改元素。
empty()判断容器中是否有元素,若无元素,则返回 true;反之,返回 false。
max_size()返回容器所能包含元素个数的最大值。这通常是一个很大的值,比如 2^32-1,所以我们很少会用到这个函数。
front()返回第一个元素的引用。
assign()用新元素替换容器中原有内容。
push_front()在容器头部插入一个元素。
emplace_front()在容器头部生成一个元素。该函数和 push_front() 的功能相同,但效率更高。
pop_front()删除容器头部的一个元素。
emplace_after()在指定位置之后插入一个新元素,并返回一个指向新元素的迭代器。和 insert_after() 的功能相同,但效率更高。
insert_after()在指定位置之后插入一个新元素,并返回一个指向新元素的迭代器。
erase_after()删除容器中某个指定位置或区域内的所有元素。
swap()交换两个容器中的元素,必须保证这两个容器中存储的元素类型是相同的。
resize()调整容器的大小。
clear()删除容器存储的所有元素。
splice_after()将某个 forward_list 容器中指定位置或区域内的元素插入到另一个容器的指定位置之后。
remove(val)删除容器中所有等于 val 的元素。
remove_if()删除容器中满足条件的元素。
unique()删除容器中相邻的重复元素,只保留一个。
merge()合并两个事先已排好序的 forward_list 容器,并且合并之后的 forward_list 容器依然是有序的。
sort()通过更改容器中元素的位置,将它们进行排序。
reverse()反转容器中元素的顺序。

除此之外,C++ 11 标准库还新增加了 begin() 和 end() 这 2 个函数,和 forward_list 容器包含的 begin() 和 end() 成员函数不同,标准库提供的这 2 个函数的操作对象,既可以是容器,还可以是普通数组。当操作对象是容器时,它和容器包含的 begin() 和 end() 成员函数的功能完全相同;如果操作对象是普通数组,则 begin() 函数返回的是指向数组第一个元素的指针,同样 end() 返回指向数组中最后一个元素之后一个位置的指针(注意不是最后一个元素)。

forward_list 容器还有一个std::swap(x , y)非成员函数(其中 x 和 y 是存储相同类型元素的 forward_list 容器),它和 swap() 成员函数的功能完全相同,仅使用语法上有差异。

下面的样例演示了部分成员函数的用法:

#include <iostream>
#include <forward_list>
using namespace std;

int main()
{
    std::forward_list<int> values{1,2,3};
    values.emplace_front(4); // {4,1,2,3}
    values.emplace_after(values.before_begin(), 5); // {5,4,1,2,3}
    values.reverse(); // {3,2,1,4,5}
    for (auto it = values.begin(); it != values.end(); ++it) {
        cout << *it << " ";
    }
    return 0;
}

运行结果为:

3 2 1 4 5

和使用forward_list容器相关的函数

我们知道,forward_list 容器中是不提供 size() 函数的,但如果想要获取 forward_list 容器中存储元素的个数,可以使用头文件 <iterator> 中的 distance() 函数。举个例子:

#include <iostream>
#include <forward_list>
#include <iterator>
using namespace std;

int main()
{
    std::forward_list<int> my_words{1,2,3,4};
    int count = std::distance(std::begin(my_words), std::end(my_words));
    cout << count;
    return 0;
}

运行结果为:

4

并且,forward_list 容器迭代器的移动除了使用 ++ 运算符单步移动,还能使用 advance() 函数,比如:

#include <iostream>
#include <forward_list>
using namespace std;

int main()
{
    std::forward_list<int> values{1,2,3,4};
    auto it = values.begin();
    advance(it, 2);
    while (it!=values.end())
    {
        cout << *it << " ";
        ++it;
    }
    return 0;
}

运行结果为:

3 4

3. forward_list 容器的创建

由于 forward_list 容器以模板类 forward_list<T>(T 为存储元素的类型)的形式被包含在 <forward_list> 头文件中,并定义在 std 命名空间中。因此,在使用该容器之前,代码中需包含下面两行代码:

#include <forward_list>
using namespace std;

std 命名空间也可以在使用 forward_list 容器时额外注明,两种方式都可以。

创建 forward_list 容器的方式,大致分为以下 5 种。

  1. 创建一个没有任何元素的空 forward_list 容器:
std::forward_list<int> values;

由于 forward_list 容器在创建后也可以添加元素,因此这种创建方式很常见。

  1. 创建一个包含 n 个元素的 forward_list 容器:
std::forward_list<int> values(10);

通过此方式创建 values 容器,其中包含 10 个元素,每个元素的值都为相应类型的默认值(int类型的默认值为 0)。

  1. 创建一个包含 n 个元素的 forward_list 容器,并为每个元素指定初始值。例如:
std::forward_list<int> values(10, 5);

如此就创建了一个包含 10 个元素并且值都为 5 的 values 容器。

  1. 在已有 forward_list 容器的情况下,通过拷贝该容器可以创建新的 forward_list 容器。例如:
std::forward_list<int> value1(10);
std::forward_list<int> value2(value1);

注意,采用此方式,必须保证新旧容器存储的元素类型一致。

  1. 通过拷贝其他类型容器(或者普通数组)中指定区域内的元素,可以创建新的 forward_list 容器。例如:
// 拷贝普通数组,创建forward_list容器
int a[] = { 1,2,3,4,5 };
std::forward_list<int> values(a, a+5);
// 拷贝其它类型的容器,创建forward_list容器
std::array<int, 5> arr{ 11,12,13,14,15 };
std::forward_list<int> values(arr.begin()+2, arr.end()); // 拷贝arr容器中的{13,14,15}

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

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

相关文章

解决ubuntu cuda版本nvcc -V和nvidia-smi不一致问题

在使用nvcc -V和nvidia-smi查看cuda版本时不一致&#xff1a; nvcc -V版本是10.1 nvidia-smi的版本是12.2 上面如果能显示版本&#xff0c;所以是已经有驱动&#xff0c;首先要删除之前的驱动&#xff1a; 1、执行以下命令&#xff0c;删除旧版本的驱动 sudo apt-get purge …

数据库用户管理

一 目录 一 新建用户 二 用户名的改变 三 删除用户 四 修改用户密码root用户 五 忘记mysql的密码时候怎么办 六 数据库的权限赋予 ​编辑 七 查询用户名的权限 八 权限的撤销 九总结 新建用户 CREATE USER 用户名来源地址 [IDENTIFIED BY [PASSWORD] 密码]; 只是一个用…

node中表单验证捕获第三方库

1.安装 npm install escook/express-joi npm install joi17.4.0 2.使用 2.1创建一个schema文件夹 说明&#xff1a;用于表单规则集&#xff0c;设置表单的规划的 // 导入定义验证的包 const joi require("joi");// 定义用户名和密码的验证规则 const username j…

数据结构(王卓版)——初识数据结构

一、数据结构讲什么&#xff1a; 程序数据结构算法 数据结构的基础以及数据结构的应用方向。 数据、数据元素、数据项、数据对象 数据结构 逻辑结构的种类 存储结构种类 主要学习顺序和链式存储结构。 有时间可以了解&#xff0c;不用重点学。 数据类型&#xff1a; 抽象数据类…

win11利用start11实现全屏菜单,磁贴配置

Win11磁贴配置 最近电脑还是升级到 win11 了。我之前采用的美化方案是桌面上的图标全部移到 win10 开始菜单里的全屏菜单上&#xff0c;用磁贴贴一排。每次要访问文件的时候都去开始菜单里找&#xff0c;而不是放在桌面上&#xff0c;这样桌面也可以空出来欣赏壁纸。参考配置链…

数据库压力测试方法概述

一、前言 在前面的压力测试过程中&#xff0c;主要关注的是对接口以及服务器硬件性能进行压力测试&#xff0c;评估请求接口和硬件性能对服务的影响。但是对于多数Web应用来说&#xff0c;整个系统的瓶颈在于数据库。 原因很简单&#xff1a;Web应用中的其他因素&#xff0c;…

MSP430F249 Proteus仿真智能刷卡计时计费水表系统 -0070

MSP430F249 Proteus仿真智能刷卡计时计费水表系统 -0070 Proteus仿真小实验&#xff1a; MSP430F249 Proteus仿真智能刷卡计时计费水表系统 -0070 功能&#xff1a; Protues版本&#xff1a;8. 9 程序编写&#xff1a;IAR 7.10 硬件组成&#xff1a;MSP430F249 单片机 …

auc的计算方法

方法一 用指示函数表示上式中正样本预测值大于负样本预测值的正负样本对&#xff0c;则得到 p表示预测得分。 在给出的例子中&#xff0c;包含有2个正样本(A, B)和3个负样本(C, D, E)&#xff0c;因此一共有6个(2*3)正负样本对&#xff0c;即公式中分母为6。 接下来计算公式…

Rogue DHCP Server攻击(仿冒DHCP Server攻击)

目录 事件原理 DHCP 仿冒攻击 防护方法 事件原理 攻击原理:攻击者仿冒DHCP Server向客户端分配错误的IP地址以及错误的网关等信息,导致用户无法正常的访问网络。漏洞分析:DHCP客户端收到DHCP Server的DHCP消息之后,无法区分这些DHCP消息是来自仿冒的DHCP Server还是…

【NLP】BERT和原理揭示

一、说明 BERT&#xff08;来自transformer的双向编码器表示&#xff09;是Google AI Language研究人员最近发表的一篇论文。它通过在各种NLP任务中展示最先进的结果&#xff0c;在机器学习社区引起了轰动&#xff0c;包括问答&#xff08;SQuAD v1.1&#xff09;&#xff0c;自…

PostgreSQL如何设置主键自增?

本文主题&#xff1a;采用Navicat 连接pgSQL库&#xff0c;如何创建表&#xff0c;如何设置主键自增&#xff1f; 1. 如何通过Navicat 连接pgSQL创建表 详细创建过程可以参考天翼云文章&#xff1a; 参考链接&#xff1a;https://www.ctyun.cn/document/10000047/10030641 2…

一篇完整学习JUC并发编程(包含实例源码)

文章目录 JUC并发编程1、什么是JUC?2、线程和进程并发、并行线程有几个状态&#xff1f; 6个wait/sleep区别&#xff1f; 3、Lock锁传统sychronized锁卖票实例使用Lock锁卖票实例sychnorized 和 lock锁区别 4、生产者和消费者问题synorchized版生产者和消费者问题虚假唤醒问题…

【UT学习记录】

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 Part1&#xff1a;Mock Part2&#xff1a;PowerMock Part3:Junit 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文…

Linux进程信号(二)

信号保存与捕捉 1.相关概念2.信号在内核中的示意图3.信号集4.信号集操作函数5.内核态与用户态6.信号捕捉7.sigaction8.可重入函数8.volatile9.SIGCHLD信号 &#x1f31f;&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f;&#x1f31f; &#x1f680;&#…

hbuilderX自定义主题仿vscode暗黑主题

目录 hbuilderX自定义主题仿vscode暗黑主题 效果图 设置方式&#xff08;把主题代码复制进来即可&#xff09; 是基于雅蓝主题自定义的 设置好后需要切换到雅蓝主题 hbuilderx保存时自动整理代码 1.首先在顶部栏&#xff0c;找到工具&#xff0c;打开设置 2.点击旁边的编…

uniapp做微信小程序,自定义checkbox和radio的样式

用uniapp做个微信小程序&#xff0c;其中有用到自定义checkbox和radio的样式&#xff1b;代码记录如下&#xff1a; 自定义checkbox 在App.vue中写入样式&#xff1a; checkbox.red .wx-checkbox-input,checkbox.red .uni-checkbox-input {background-image: url(/static/ima…

MySQL锁定:死锁及其避免方法

文章目录 一、MySQL锁定和并发控制的重要性二、MySQL锁机制回顾2.1 锁类型&#xff1a;共享锁和排他锁2.2 锁粒度&#xff1a;行级锁和表级锁 三、死锁的原因和场景四、检测和解决死锁4.1 死锁检测算法4.2 死锁处理策略4.3 手动处理死锁 五、死锁的预防和避免分布式环境下&…

驱动程序设计 利用RTC显示年月日时分秒到终端 7.11

驱动控制RTC 用户需求&#xff1a;写一个RTC时钟控制的驱动&#xff0c;实现RTC显示年月日时分秒到用户端 驱动需求&#xff1a;设备&#xff1a;RTC模块 功能&#xff1a;打印显示 寄存器操作&#xff1a; 原理图&#xff1a; 设备–>pin–>设备控制芯片 ​ 驱动需求 …

信号波形时序图常用工具推荐

Refer: 下载&#xff1a;画时序图的四大神器_可编程器件-面包板社区 (eet-china.com) 软件工程师&#xff0c;习惯使用StarUML画Timing Diagram, 硬件工程师建议使用一下软件。 1、AndyTiming 免费的&#xff0c;这个有一个知乎的博文可以参考 https://zhuanlan.zhihu.com/p…

Android 中利用多个Button组合实现选项切换效果

效果图&#xff1a; xml布局: <LinearLayoutandroid:orientation"horizontal"android:layout_width"match_parent"android:layout_height"50dp"android:gravity"center"android:background"color/White">​<Linear…