list
须知:在尖括号中定义你容器里的元素类型 eg:list<int> name ,介绍的函数并不是全部函数,没介绍的在其他篇幅中可能有介绍,stl中函数大部分都是通用的。且list 和forward_list的存储空间在内存中不是连续的,而是随机的。因此后面函数的参数position是不可以用begin()+val这种方式来放入参数列表的
区别于vector,list不能随机访问元素。list与forward_list 不同,List容器实现为双向链表,所以提供了对数据的双向顺序访问。双向链表允许从任何位置进行插入和删除操作,在大小为0的时候也是有意义的此时list.begin()和list.end()指向相同的位置。
可头插,尾插
头插:.push_front() 尾插:.push_back()
可头删,尾删
头删:.pop_front() 尾删:.pop_back()
访问特定元素
可以通过.front()和.back()访问头元素和尾元素,可直接通过该函数进行赋值。
构造函数赋值:
list<int> l1(2) //两个大小,元素默认为0
list<int>l1(2,5)//两个大小,元素为5
查看大小.size()
构造函数赋值:list<int> li(5),默认分配0值,也可以list<int> li2(li.begin(),li.end())从li的里面拿值进行赋值,也可以直接拿容器li list<int> li2(li)相当于构造一个包含现有列表中存在的每个元素的副本的列表
assign()函数
通过替换旧值将新值分配给列表。此成员函数将 val 分配给列表的每个元素。
li.assign(5,10)
#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> l(3);
cout<<l.size()<<endl;
l.assign(6, 10);
cout<<l.size()<<endl;
cout << "List contains following element" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
return 0;
}
这里注意,如果在声明的时候定义了较小或较大的空间之后,比如3,再后面用assign函数,函数会根据你的参数内容更改容器中的大小,如果参数大小大于原定义的,函数就会扩大,参数小于原定义的,函数就会缩小。
运行结果:
列表删除所有元素,并将大小设为0来销毁列表
.clear()
插入函数emplace()
通过在给定位置插入新元素来扩展列表。 这个成员函数增加了列表的大小。
当你使用 emplace
函数在容器的指定位置插入元素时,插入的位置是在 参数位置的前面
区别:
- 对于像
std::vector
和std::deque
这样的顺序容器,emplace
会在指定的迭代器位置之前插入元素。 - 对于像
std::set
和std::map
这样的关联容器,emplace
会根据容器的排序规则插入元素,而不严格按照传入的迭代器位置插入。
#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> l = {3, 4, 5};
auto it = l.emplace(l.begin(), 2);//begin()指头元素,所以在3前插入2
l.emplace(it, 1);//it 保存emplace的返回值
cout << "List contains following element" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
emplace()返回一个随机访问迭代器,它指向新放置的元素。所以上面的it迭代器指向的是插入2的位置。
merge()函数
将两个排序列表合并为一个。列表应按升序排序。
#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> l1 = {1, 5, 11, 31};
list<int> l2 = {10, 20, 30};
l2.merge(l1);
cout << "List contains following elements after merge operation" << endl;
for (auto it = l2.begin(); it != l2.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
要想合并降序排序可以l2.merge(l1,cmp_fun)
remove()函数
从列表中删除元素与值匹配并通过删除元素的数量减少列表的大小
参数是需要匹配删除掉的元素
#include <iostream>
#include <list>
using namespace std;
int main(void) {
list<int> l = {3, 1, 2, 3, 3, 4, 5, 3};
cout << "List contents before remove opration" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
l.remove(3);
cout << "List contents after remove opration" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
有趣的是还有一个条件删除函数remove_if()参数为一个函数,需要删除返回函数返回true的元素,所以函数一般返回值都是bool,举个栗子:
#include <iostream>
#include <list>
using namespace std;
bool foo(int n) {
return (n > 5);
}
int main(void) {
list<int> l = {1, 2, 3, 4, 5, 6, 7, 8, 9};
cout << "Contents of list before remove_if operation" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
/* remove all elements larger than 5 */
l.remove_if(foo);
cout << "Contents of list after remove_if operation" << endl;
for (auto it = l.begin(); it != l.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
resize(n)函数
改变列表的大小。如果 n 小于当前大小,则销毁额外的元素。
且会保留原来的值
如果 n 大于当前容器大小,则在列表末尾插入新元素。如果指定了 val,则新元素以 val 开头。
swap()函数
与另一个交换第一个列表的内容。 如有必要,此功能会更改列表的大小。
#include <iostream>
#include <list>
using namespace std;
int main(void) {
// 初始化列表 l1 和 l2,分别包含一些元素
list<int> l1 = {1, 2, 3};
list<int> l2 = {10, 20, 30, 40, 50};
// 输出交换操作前 l1 中的元素
cout << "交换操作前,列表 l1 包含以下元素" << endl;
for (auto it = l1.begin(); it != l1.end(); ++it)
cout << *it << endl;
// 输出交换操作前 l2 中的元素
cout << "交换操作前,列表 l2 包含以下元素" << endl;
for (auto it = l2.begin(); it != l2.end(); ++it)
cout << *it << endl;
// 执行 l1 和 l2 的交换操作
l1.swap(l2);
// 输出交换操作后 l1 中的元素
cout << "交换操作后,列表 l1 包含以下元素" << endl;
for (auto it = l1.begin(); it != l1.end(); ++it)
cout << *it << endl;
// 输出交换操作后 l2 中的元素
cout << "交换操作后,列表 l2 包含以下元素" << endl;
for (auto it = l2.begin(); it != l2.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
可使用的函数
:reverse()翻转函数,参数是指针/迭代器.
.unique()删除重复元素
.insert()参数可参照下面的insert_after()
forward_list
须知:在尖括号中定义你容器里的元素类型 forward_list<int> f1
使用前提,#include<forward_list>
理解:容器保存相同类型数据的对象,forward_list容器被实现为单链表,所以访问其数据只能是单向顺序访问。单链表允许在任何位置进行插入和删除操作。
forward_list函数与list大致都可以通用
emplace_after(position,val)
见名知义,在 forward_list 中的 position之后构造并插入新元素val,并将 forward_list 的大小增加
#include <iostream>
#include <forward_list>
using namespace std;
int main(void) {
forward_list<int> fl = {1, 3, 4, 5};
fl.emplace_after(fl.begin(), 2);
cout << "List contains following elements" << endl;
for (auto it = fl.begin(); it != fl.end(); ++it)
cout << *it << endl;
return 0;
}
运行结果:
emplace_front(val)
类似于头插,由于位置固定所以只需要一个参数,val为插入的数据。
insert_after() // forward_list独有
参数同insert
1.(position,val) val为单个元素数据
2.(position,li)li为对象,可以是另外一个forward_list容器
3.(position,n,val)n为插入个数,val为插入的数据