c++中的list容器其实就是我们前面在数据布局时学习过的 带头双向链表,在c++中,研发这将如许的数据布局举行封装。本日我们=就来举行深入的学习,来看看作为C++STL容器
之一,list暗含着什么样的秘密。
1.1list容器的先容
先容文档:cplusplus.com/reference/list/list/?kw=list
通过这幅图其实就可以简朴的解释list容器的根本布局, list本质上就是一个双向的循环带头链表。
1.2list的使用
list容器和前面的string 和 vector容器非常的像,根本的功能本质上那个就是实现对数据布局中的造数据实现相应的增删查改。
下买呢我们还是先来先容一些常见的list容器接口,来深入的学习list容器。
1.2.1 list的构造
构造函数(construct) | 接口说明 | list (size_type n, const value_type& val = value_type()) | 构造list中包含了n个值为val的元素 | list() | 构造空的list | list(const list&x) | 构造拷贝函数 | list(Inputiterator first, inputliterator last) | 用(first, last)区间中的元素构造list | 1.2.1.1 list (size_type n, const value_type& val = value_type())
- #include<list>
- #include<iostream>
- using namespace std;
- int main()
- {
- list<int> s1(4,3);
- //迭代器的使用,后面会说
- for (auto i : s1)
- {
- cout << i << endl;
- }
- return 0;
- }
复制代码
1.2.1.2 list(const list&x)
- #include<list>
- #include<iostream>
- using namespace std;
- int main()
- {
- list<int> s1(4, 3);
-
- for (auto i : s1)
- {
- cout << i;
- }
- cout << endl;
- s1.push_back(4);//在s1的尾部插入一个数据
- for (auto i : s1)
- {
- cout << i ;
- }
- cout << endl;
- //演示list(const list& x)
- list<int> s2(s1);
- for (auto i : s1) cout << i;
- cout << endl;
- return 0;
- }
复制代码
1.2.1.3 list(Inputiterator first, inputliterator last)
通过迭代器来拷贝原来链表指定区域中的元素
- list<int> s1 = { 1,2,3,4,5 };
- cout << "s1:";
- for (auto i : s1) cout << i;
- cout << endl;
- //演示 list(inputliretator first, inputliterator last)
- list<int> s2(s1.begin(), s1.end());
- cout << "s2:";
- for (auto i : s2) cout << i;
- cout << endl;
复制代码
1.2.2 list iterator的使用
函数的声明 | 接口说明 | begin + end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 | rbegin+rend | 返回第一个元素的 reverse_literator, 即end位置,返回最后一个元素下一个元素的 reverse_iterator, 即begin的位置 |
注意:
1. begin与end为正向迭代器, 对迭代器的执行 ++ 操作时,迭代器向后移动。
2. rbegin(end)与 rend(begin) 为反向迭代器, 对迭代器的++ 操作,迭代器向前移动。
接下来是一些迭代器相干的代码展示:
正向迭代器
- #include<iostream>
- #include<list>
- using namespace std;
- // list迭代器的使用
- // 注意:遍历链表只能用迭代器和范围for
- void PrintList(const list<int>& l)
- {
- // 注意这里调用的是list的 begin() const,返回list的const_iterator对象
- for (list<int>::const_iterator it = l.begin(); it != l.end(); ++it)
- {
- cout << *it << " ";
- // *it = 10; 编译不通过
- }
- cout << endl;
- }
复制代码
反向想迭代器
- void TestList2()
- {
- int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
- list<int> l(array, array + sizeof(array) / sizeof(array[0]));
- // 使用正向迭代器正向list中的元素
- // list<int>::iterator it = l.begin(); // C++98中语法
- auto it = l.begin(); // C++11之后推荐写法
- while (it != l.end())
- {
- cout << *it << " ";
- ++it;
- }
- cout << endl;
- // 使用反向迭代器逆向打印list中的元素
- // list<int>::reverse_iterator rit = l.rbegin();
- auto rit = l.rbegin();
- while (rit != l.rend())
- {
- cout << *rit << " ";
- ++rit;
- }
- cout << endl;
- }
复制代码
1.2.3 list capacity
函数申明 | 接口说明 | empty | 检测list是否为空, 是就返回true,否则返回false | size | 返回list中有效节点的个数 | 1.2.4 list element access
函数的声明 | 接口说明 | front | 返回list的第一个节点的值 | back | 返回list的最后一个节点的值 |
- int main()
- {
- list<int> l1;
- //让程序随机生成 1-100之内的数字
- srand((uint32_t)time(NULL));
- for (int i = 0; i < 10; i++)
- {
- int x = rand() % 100;
- l1.push_back(x);
- }
- //打印链表的元素
- for (auto i : l1)
- {
- cout << i << " ";
- }
- cout << endl;
- cout << "此时l1的大小是:" << l1.size() << endl;
- cout << "链表的首元素:" << l1.front() << endl << "链表的尾元素:" << l1.back() << endl;
- }
复制代码
1.2.5 list modifiers
函数申明 | 接口说明 | push_front | 在list首元素前插入值为val1的元素
| pop_front | 删除list元素中的第一个元素 | push_back | 在list的尾部插入元素 | pop_back | 删除list的最后一个元素 | insert | 在list position位置插入元素 | swap | 交换两个list中的元素 | erase | 删除指定位置的值 | clear | 清除list中的有效元素 | 关于上上面的接口,这里博主就提供一些测试用的函数,各人可以拿去测试一下:
- // list插入和删除
- // push_back/pop_back/push_front/pop_front
- void TestList3()
- {
- int array[] = { 1, 2, 3 };
- list<int> L(array, array + sizeof(array) / sizeof(array[0]));
- // 在list的尾部插入4,头部插入0
- L.push_back(4);
- L.push_front(0);
- PrintList(L);
- // 删除list尾部节点和头部节点
- L.pop_back();
- L.pop_front();
- PrintList(L);
- }
- // insert /erase
- void TestList4()
- {
- int array1[] = { 1, 2, 3 };
- list<int> L(array1, array1 + sizeof(array1) / sizeof(array1[0]));
- // 获取链表中第二个节点
- auto pos = ++L.begin();
- cout << *pos << endl;
- // 在pos前插入值为4的元素
- L.insert(pos, 4);
- PrintList(L);
- // 在pos前插入5个值为5的元素
- L.insert(pos, 5, 5);
- PrintList(L);
- // 在pos前插入[v.begin(), v.end)区间中的元素
- vector<int> v{ 7, 8, 9 };
- L.insert(pos, v.begin(), v.end());
- PrintList(L);
- // 删除pos位置上的元素
- L.erase(pos);
- PrintList(L);
- // 删除list中[begin, end)区间中的元素,即删除list中的所有元素
- L.erase(L.begin(), L.end());
- PrintList(L);
- }
- // resize/swap/clear
- void TestList5()
- {
- // 用数组来构造list
- int array1[] = { 1, 2, 3 };
- list<int> l1(array1, array1 + sizeof(array1) / sizeof(array1[0]));
- PrintList(l1);
- // 交换l1和l2中的元素
- list<int> l2;
- l1.swap(l2);
- PrintList(l1);
- PrintList(l2);
- // 将l2中的元素清空
- l2.clear();
- cout << l2.size() << endl;
- }
复制代码 好,本日的学习就到这里,我们下期再见,拜!!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |