STL - forward_list 容器

forward_list 基础:

关于forward_list容器:

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

注意:

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

1、forward_list 创建:

#include<forward_list>
using namespace std;
std::forward_list<int> values; //创建一个没有任何元素的空forward_list 容器
std::forward_list<int> values(10); //创建一个包含10个元素的forward_list 容器
std::forward_list<int> values(10, 5); // 创建一个包含 n 个元素的 forward_list 容器,并为每个元素指定初始值
//在已有 forward_list 容器的情况下,通过拷贝该容器可以创建新的 forward_list 容器
std::forward_list<int> value1(10);
std::forward_list<int> value2(value1);
//拷贝普通数组,创建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}

2、访问 / 赋值:

迭代器:
分为:begin、end、cbegin、cend、before_begin、cbefore_begin

// 使用方法
auto it=fl.begin(); //相当于指针,用 *it 访问
fl.begin(); //返回指向fl第一个元素的迭代器
fl.end(); //返回指向fl最后一个元素下一个元素的迭代器
fl.cbegin(); //返回指向fl第一个元素的迭代器, 类型为const
fl.before_begin(); //返回指向第一个元素之前的迭代器

注意:
不支持下标 [] 和 at 函数随机访问容器内元素,只能通过迭代器访问
assign (赋值函数):

fl.assign(2, 3);
//将 2 个 3 赋值给 fl
//例:fl={5,6,7}
//运行之后 fl={3,3}
fl.assign(fl1.begin(), fl1.end());
//将区间内的元素赋值给 fl
//例:fl={5,6,7}, fl1={1,2,3,4}
//运行之后 fl={1,2,3,4}

swap (交换函数):

fl.swap(fl1);
//交换两个容器的内容
//例:fl={1,2,3,4}, fl1={5,6,7}
//运行之后, fl={5,6,7}, fl1={1,2,3,4}

常用函数:

fl.push_front(4);
//在头部插入元素 4 
//例:fl={1,2,3}
//运行之后, fl={4,1,2,3}
fl.pop_front();
//删除第一元素
//例:fl={1,2,3,4}
//运行之后, fl={2,3,4}
fl.front();
//返回第一元素
//例:fl={1,2,3,4}
//fl.front()就等于 1
fl.clear();
//清空容器
fl.empty();
//容器为空返回 true, 否则返回 false

3、长度 / 空间 / 容量相关函数

//该函数返回可以存储到forward_list中的最大数字。
fl.max_size();
//更改 forward_list 的大小。如果 n 小于当前大小,则销毁额外的元素。如果 n 大于当前容器大小,则在 forward_list 的末尾插入新元素。
fl.resize(6);
//设置 fl 的 size,如果尺寸变大,新空间全部用 2 代替
fl.resize(3, 2);

4、添加 / 删除

insert_after (插入函数):

fl.insert_after(fl.begin(), 3);
//在位置之后插入元素 3
//例: fl={1,2}
//运行之后 fl={1,3,2}
fl.insert_after(fl.begin(), 2, 3);
//在位置之后插入 2 个元素 3
//例: fl={1,2}
//运行之后 fl={1,3,3,2}
fl.insert_after(fl.begin(), fl1.begin(), fl1.end());
//在 fl 位置之后插入 fl1 区间的元素
//例: fl={1,2}, fl1={5,6,7},
//运行之后 fl={1,5,6,7,2}

emplace (插入函数):

fl.emplace_front();
//在容器的头部插入一个元素, 默认为 0
//例: fl={1,2}
//运行之后 fl={0,1,2}
fl.emplace_front(5);
//在容器的头部插入一个元素 5
//例: fl={1,2}
//运行之后 fl={5,1,2}
fl.emplace_after(fl.begin(), 5);
//在位置之后插入元素 5
//例: fl={1,2}
//运行之后 fl={1,5,2}

注意:
emplace系列 / push_front 和 insert的区别:
原理上:emplace 是直接在容器的位置上创建变量, 不需要生成对象,push_front / insert 是先生成对象, 然后将对象的内容复制到容器里面
功能上:emplace / push_front 只能插入一个元素,insert 可以插入多个元素,性能上emplace 的速度要更快一点
merge (合并函数):

fl.merge(fl1);
//将 fl1 的全部元素转移到 fl
//保证转移之前的 fl/fl1 有序, 转移后的 fl 同样有序, 默认升序
//例: fl={1,3,5}, fl1={2,4,6}
//执行之后, fl={1,2,3,4,5,6}, fl1={};
fl.merge(fl1, greater <int>());
//将 fl1 的全部元素转移到 fl, 排序准则为降序
//例: fl={5,3,1}, fl1={6,4,2}
//执行之后, fl={6,5,4,3,2,1}, fl1={};
fl.merge(fl1, op);
// 将 fl1 的全部元素转移到 fl, 排序准则为 op

splice_after (拼接函数):

fl.splice_after(fl.begin(), fl1);
// 将 fl1 转移到 fl 的位置之后
//例: fl={1,2}, fl1={5,6,7},
//运行之后 fl={1,5,6,7,2}, fl1={};
fl.splice_after(fl.begin(), fl1, fl1.begin());
//将 fl1 所指元素转移到 fl 的位置之后
//例: fl={1,3,5}, fl1={2,4,6}
//执行之后, fl={1,2,3,5}, fl1={4,6};
fl.splice_after(fl.begin(), fl1, fl1.begin(),fl1.end());
//将 fl1 区间内元素转移到 fl 的位置之后
//例: fl={1,2}, fl1={5,6,7},
//运行之后 fl={1,5,6,7,2}, fl1={};

注意:
a.函数名(b)
将容器 b 的内容插入到容器 a 中
insert: 函数就是正常的将容器 b 的内容复制插入到容器 a 中
merge: 函数在使用之前两个容器必须具有相同的顺序(升序/降序/自定义的顺序), 是将容器 b 的内容按照一定的顺序移动插入到容器 a 中, 会将容器 b 中插入的内容删除
splice: 函数是将容器 b 的内容移动插入到容器 a 中, 会将容器 b 中插入的内容删除
erase_after (删除函数)

fl.erase_after(fl.begin());
//删除指向位置之后的元素
//例: fl={1,2,3}
//运行之后 fl={1,3}, 返回指向元素 3 的迭代器
fl.erase_after(fl.begin(), fl.end());
//删除区间内的元素(保留区间内的第一个元素)
//例: fl={1,2,3}
//运行之后 fl={1}
**remove系列 (移除函数):**
fl.remove(3);
// 删除所有值为 3 的元素
//例: fl={1,2,3,3,4,3,3}
//运行之后 fl={1,2,4}
fl.remove_if([](int a) { return a > 3; });
//删除大于 3 的元素
//例: fl={1,2,3,3,4,4,5}
//运行之后 fl={1,2,3,3}
fl.remove_if(op);
// 删除使 op 为true的元素
bool op(int a) {
// 10~100 返回 false, 其余返回 true
//其实就是删除10~100之外的数
	return a < 10 || a>100;
}
//例: fl={1,2,10,50,60,100,111}
//运行之后 fl={10,50,60,100}

unique (排重函数):

fl.unique();
//删除相邻的相同元素, 只留一个
//例: fl={1,2,3,3,3,4,3,3,6}
//运行之后 fl={1,2,3,4,3,6}

注意:
erase / remove / unique 三个删除函数的区别
erase 函数是通过迭代器查找到元素之后, 进行删除
remove 函数是通过 特定条件 查到元素之后, 进行删除
unique 函数只将相邻的相同元素删除, 但是并没有真正达到排重的效果

5、更改数据

reverse (翻转函数):

fl.reverse();
//翻转容器
//例:fl={1,2,3,4}
//运行之后, fl={4,3,2,1}

sort (排序函数):

fl.sort();//升序排序
//例: fl={1,2,3,5,4,1,3}
//运行之后 fl={1,1,2,3,3,4,5}
fl.sort(greater<int>());//降序排序
//例: l={1,2,3,5,4,1,3}
//运行之后 l={5,4,3,3,2,1,1}
fl.sort(op); //以 op 为准则, 将所有元素排序

注意:

//正常来说是不会用到 unique 函数的, 他一般和 sort 成员函数配套使用, 达到将容器中相同的多余元素删除的效果(真正意义上的排重)
fl={2,5,1,6,1,3,2,4,1,5,6};
直接执行 unique 函数是不能真正做到排重的
只有先进行 sort 排序, 再执行 unique 函数, 才能达到要求
fl.sort();
fl.unique();
执行之后, fl={1,2,3,4,5,6}
posted @ 2023-03-10 23:07  盧倫  阅读(98)  评论(0)    收藏  举报