STL之list和forward_list

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::vectorstd::deque 这样的顺序容器,emplace 会在指定的迭代器位置之前插入元素。
  • 对于像 std::setstd::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为插入的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后天苦海谈话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值