本文最后更新于:2021年4月6日 晚上
STL链表list。
STL中的链表是一个双向循环链表。
其存储结构并非连续的内存空间,所以list的迭代器只支持前移和后移,它是双向迭代器,而不是像vector那样的随机访问迭代器。
list的优缺点
优点:
- 采用动态存储分配,不会造成内存浪费和溢出
- 链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素
缺点:
- 比数组要额外存储指向下一个节点的指针,需要额外耗费空间。
- 不支持随机访问,额外耗费较大。
与vector相比:插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
list的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| list<T> lst;
list(beg,end);
list(n,elem);
list(const list &lst);
assign(beg, end);
assign(n, elem);
list& operator=(const list &lst);
swap(lst);
size();
empty();
resize(num);
resize(num, elem);
push_back(elem);
pop_back();
push_front(elem);
pop_front();
insert(pos,elem);
insert(pos,n,elem);
insert(pos,beg,end);
clear();
erase(beg,end);
erase(pos);
remove(elem);
front();
back();
reverse();
sort();
|
- remove(elem) 是按照值匹配而移除, erase按照迭代器的指向而移除。
- list不支持随机访问,所以它没有
[]
或者at(index)
这样的vector类似的方法。
list的迭代器
list由于是链表实现,其迭代器不能像vector的迭代器那样强大。
list的迭代器只能做简单的自增1,自减的操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| list<int> li;
for (int i = 0; i < 100; i+=2) { li.push_back(i); li.push_front(i + 1); }
list<int>::iterator it = li.begin();
it++; it--;
|
list的sort排序
所有不支持随机访问迭代器的容器,都不可以使用标准算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| bool myCompare(int &a,int &b) { return a > b; }
void test3() {
list<int> li;
for (int i = 0; i < 100; i += 2) { li.push_back(i); li.push_front(i + 1); }
list<int>::iterator it = li.begin(); for (; it != li.end(); it++) cout << *it << " "; cout << endl;
li.sort();
it = li.begin(); for (; it != li.end(); it++) cout << *it << " "; cout << endl;
li.sort(myCompare);
it = li.begin(); for (; it != li.end(); it++) cout << *it << " "; cout << endl;
}
|
总结:
- 算法
<algorithm>
有sort()排序算法,但是这个算法是只支持可以随机访问的容器。由于list不支持,所以其自己提供了实现函数。
- 对于自定义的数据类型,使用list存储,如果需要进行排序,必须要自行指定排序规则。
unique() —— 去重函数
unique() 是删除容器中相邻重复的元素。
所以应当先进行排序,使用list的sort()
,然后再调用unique
,才能尽可能地删去重复地元素。
使用情景
- 注意list不支持随机访问、使用下标进行访问。只能从头遍历整个链表。