1.什么是list?
在官网中,对list有这样的介绍:
即:list是允许在序列中的任何位置进行恒定时间的插入和删除操作的序列容器,并且可以双向迭代。
于是对list便有这样的介绍:
1. list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
2. list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
3. list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,以让其更简单高效。
4. 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
5. 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的影响因素)
2.list的构造
list的常见构造有:
①list()——构造空的list;
②list (size_type n, const value_type& val = value_type())——构造一个有n个值为val的元素的list;
③list (const list& x)——拷贝构造函数;
④list (InputIterator first, InputIterator last)——用[first, last)区间中的元素构造list。
#include <iostream> #include<list> using namespace std; int main() { list<int> l1;//①构造空的list list<int> l2(4, 200);//②构造一个有n个值为val的元素的list list<int> l3(l2);//③l2拷贝构造l3 list<int> l4(l2.begin(), l2.end());//用l2的[begin(),end())构造l4 //范围for遍历l1、l2、l3、l4 for (auto e : l1) { cout << e << " "; } cout << endl; for (auto e : l2) { cout << e << " "; } cout << endl; for (auto e : l3) { cout << e << " "; } cout << endl; for (auto e : l4) { cout << e << " "; } cout << endl; return 0; }
3.list迭代器的使用(list iterator)
在之前的文章中我们就说过,可以将迭代器看做一个指针(当然底层并不完全是指针),在这里,我们理解为该指针指向list中的某个节点。
①begin+end——返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器;
②rbegin+rend——返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的 reverse_iterator,即begin位置。
#include <iostream> #include<list> using namespace std; int main() { list<int> l; l.push_back(1); l.push_back(2); l.push_back(3); l.push_back(4); //注意list只能用范围for和迭代器访问 //使用正向迭代器访问l中的元素 list<int>::iterator it = l.begin(); { while (it != l.end()) { cout << *it << " "; ++it; } cout << endl; } //使用反向迭代器访问l中的元素 list<int>::reverse_iterator rit = l.rbegin(); { while (rit != l.rend()) { cout << *rit << " "; ++rit; } cout << endl; } return 0; }
4.list capacity
①empty——检测list是否为空,是返回true,否则返回false;
②size——返回list中有效节点的个数。
#include <iostream> #include<list> using namespace std; int main() { list<int> l; l.push_back(1); l.push_back(2); l.push_back(3); l.push_back(4); if (!l.empty()) { cout << l.size() << endl; } return 0; }
5.list modifiers
①push_front——在list首元素前插入值为val的元素;
②pop_front——删除list中第一个元素;
③push_back——在list尾部插入值为val的元素;
④pop_back——删除list中最后一个元素;
⑤insert——在list position 位置中插入值为val的元素;
⑥erase——删除list position位置的元素;
⑦swap——交换两个list中的元素;
⑧clear——清空list中的有效元素。
#include <iostream> #include<list> using namespace std; int main() { list<int> l(4, 200); l.push_front(100);//在list首元素前插入值为val的元素; for (auto e : l) { cout << e << " "; } cout << endl; l.pop_front();//删除list中第一个元素; for (auto e : l) { cout << e << " "; } cout << endl; l.push_back(300);//在list尾部插入值为val的元素; for (auto e : l) { cout << e << " "; } cout << endl; l.pop_back();//删除list中最后一个元素; for (auto e : l) { cout << e << " "; } cout << endl; l.insert(++l.begin(), 150);//在begin()+1位置插入150 for (auto e : l) { cout << e << " "; } cout << endl; l.erase(++l.begin());//删除begin()+1位置的数据 for (auto e : l) { cout << e << " "; } cout << endl; list<int> ll(3, 100); cout << "交换前l="; for (auto e : l) { cout << e << " "; } cout << "ll="; for (auto e : ll) { cout << e << " "; } cout << endl; l.swap(ll);//交换l与ll的元素 cout << "交换后l="; for (auto e : l) { cout << e << " "; } cout << "ll="; for (auto e : ll) { cout << e << " "; } cout << endl; l.clear(); for (auto e : l) { cout << e << " "; } cout << endl; return 0; }
6.list的其他操作
①reverse——对list逆置;
②sort——对list排序;
③merge——将两个有序list归并为一个有序的list(无序时可调用sort先排序);
④unique——去重(去重要求所有相同的值要相邻,所以在使用unique之前最好也先调用sort);
⑤remove——相当于find+erase;
#include <iostream> #include <list> using namespace std; int main() { list<int> l1; l1.push_back(4); l1.push_back(2); l1.push_back(3); l1.push_back(1); cout << "排序前:"; for (auto e : l1) { cout << e << " "; } cout << endl; l1.sort();//排序 cout << "排序后:"; for (auto e : l1) { cout << e << " "; } cout << endl; l1.reverse(); cout << "逆置后:";//逆置 for (auto e : l1) { cout << e << " "; } cout << endl; list<int> l2,l3; l2.push_back(4); l2.push_back(2); l2.push_back(3); l2.push_back(1); l3.push_back(4); l3.push_back(4); l3.push_back(5); l3.push_back(7); l2.sort(); l3.sort(); l2.merge(l3);//归并 for (auto e : l2) { cout << e << " "; } cout << endl; l2.unique();//去重 for (auto e : l2) { cout << e << " "; } cout << endl; return 0; }