c++学习——list容器的使用学习
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;
}
好,今天的学习就到这里,我们下期再见,拜!!