链表这种数据结构想必大家都不陌生吧!通过指针链接数据,就像锁链一样将数据”穿“起来,充分利用了”零碎内存“,提高内存空间利用率!如果读者还不熟悉链表这种数据结构,可自行跳转《链表》去学习一下链表。在STL库中,list是以双向链表的身份进入序列式容器集合的。每一个节点(node)都具备一前一后各一个指针,分别指向前节点后后节点,可以想到首节点前指针为nullptr,尾节点后指针为nullptr。链表不同于vector、deque等容器,不能重载'[]'(要求内存地址保持连续性),所以不能同过'[]'进行元素访问。接下来,我将为您展示如何创建list容器以及展示list内常用成员函数。
如何创建list?请阅读代码:
#include<bits/stdc++.h> #include<list> /* 如何创建list容器 */ using namespace std; void test() { list<int> l1;//直接创建 list<int> l2{1,2,3,4,5};//列表初始化 list<int> l3(l2);//深拷贝 list<int> l4; l4=l2;//'=' 重载 list<int> l5(5,0) ;//初始为n个体的形式 list<int> l6(5) ;//初始为n个默认值,比如int类型默认是0,char类型默认是\0等 } int main(){ test(); return 0; }
编译后没报错,也是成功学会了list的创建。
接下来我将展示一些list常用成员函数:
函数 | 功能描述 |
---|---|
front() | 返回第一个元素的引用 |
back() | 返回最后一个元素的引用 |
begin() / cbegin() | 返回指向第一个元素的迭代器 |
end() / cend() | 返回末尾迭代器(尾后) |
rbegin() / crbegin() | 返回逆向起始迭代器 |
rend() / crend() | 返回逆向末尾迭代器 |
empty() | 检查列表是否为空 |
size() | 返回元素数量 |
max_size() | 返回可容纳的最大元素数 |
clear() | 清除所有内容 |
insert(const_iterator pos, const T& value) | 在pos前插入value |
insert(const_iterator pos, size_type n, const T& value) | 在pos前插入n个value |
insert(const_iterator pos, InputIt first, InputIt last) | 在pos前插入范围元素 |
emplace(const_iterator pos, Args&&... args) | 在pos前原位构造元素 |
erase(const_iterator pos) | 删除pos处的元素 |
erase(const_iterator first, const_iterator last) | 删除[first,last)范围的元素 |
push_back(const T& value) | 在末尾插入元素 |
push_back(T&& value) | 在末尾插入元素(移动) |
emplace_back(Args&&... args) | 在末尾原位构造元素 |
pop_back() | 删除末尾元素 |
push_front(const T& value) | 在开头插入元素 |
push_front(T&& value) | 在开头插入元素(移动) |
emplace_front(Args&&... args) | 在开头原位构造元素 |
pop_front() | 删除开头元素 |
resize(size_type count) | 调整大小为count个元素 |
resize(size_type count, const T& value) | 调整大小并用value初始化新元素 |
swap(list& other) | 交换两个列表的内容 |
merge(list& other) | 合并两个有序列表 |
merge(list&& other) | 合并两个有序列表(移动) |
merge(list& other, Compare comp) | 用自定义比较函数合并 |
splice(const_iterator pos, list& other) | 将other所有元素移动到pos前 |
splice(const_iterator pos, list&& other) | 移动所有元素到pos前 |
splice(const_iterator pos, list& other, const_iterator it) | 移动单个元素到pos前 |
splice(const_iterator pos, list& other, const_iterator first, const_iterator last) | 移动元素范围到pos前 |
remove(const T& value) | 移除所有等于value的元素 |
remove_if(UnaryPredicate p) | 移除所有满足谓词p的元素 |
reverse() | 反转链表元素顺序 |
unique() | 删除连续的重复元素 |
unique(BinaryPredicate p) | 用谓词p删除连续"重复"元素 |
sort() | 对元素升序排序 |
虽然list容器的成员函数比较多,但是读者要想到list功能之丰富,其”不拘一格“的存储方式极大地利用空间内存,就会喜欢上这个容器。
下面我们简单创建一个链表并通过迭代器遍历所有元素:
#include<bits/stdc++.h> #include<list> /*初识list */ using namespace std; void test() { list<int> l;//直接创建 for(int i=0;i<5;++i) { l.push_back(i+1);//链表也能通过push_back()尾增元素 } cout << "当前链表存储元素为" << l.size() << "个\n"; for(list<int>::iterator it = l.begin();it!=l.end();++it)cout << *it << " ";//链表不能通过'[]'访问元素 cout << '\n'; } int main(){ test(); return 0; }
编译后结果如下:
也是简单完成链表的基本添加元素和访问元素。
总结:本节我们学会了什么是链表容器,如何创建链表,list容器结构上为双向链表且list不能通过'[]'访问元素。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程