大家好我是沐曦希💕
一、前言
list本质是带头双向循环链表,本文只对list的一些常用接口进行说明,对于其他一些接口可自行查看文档C++ Reference
二、构造
构造函数( (constructor)) | 接口说明 |
---|---|
list (size_type n, const value_type& val = value_type()) | 构造的list中包含n个值为val的元素 |
list() | 构造空的list |
list (const list& x) | 拷贝构造函数 |
list (InputIterator first, InputIterator last) | 用[first, last)区间中的元素构造list |
void testlist1()
{
list<int> lt1; // 无参构造
list<int> lt2(5, 1); // n个val构造
list<int> lt3(lt2.begin(), lt2.end()); // 迭代器区间构造
list<int> lt4(lt3); // 拷贝构造
}
三、迭代器
函数声明 | 接口说明 |
---|---|
begin + end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
rbegin +rend | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置 |
void testlist2()
{
//正向迭代器
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
list<int>::iterator it = lt1.begin();
while (it != lt1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void testlist2()
{
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
list<int>::reverse_iterator rit = lt1.rbegin();
while (rit != lt1.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
}
注意:
1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动
四、增删查改
1.头插头删
void testlist3()
{
list<int> lt;
lt.push_front(1);
lt.push_front(2);
lt.push_front(3);
lt.push_front(4);
for (const auto& e : lt)
cout << e << " ";
cout << endl;
lt.pop_front();
lt.pop_front();
for (const auto& e : lt)
cout << e << " ";
cout << endl;
}
2.尾插尾删
void testlist4()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
for (const auto& e : lt)
cout << e << " ";
cout << endl;
lt.pop_back();
lt.pop_back();
for (const auto& e : lt)
cout << e << " ";
cout << endl;
}
3.查找和插入
在list容器中没有提供find函数,可以通过算法库提供find进行查找
#include<algorithm>
template <class InputIterator, class T>
InputIterator find (InputIterator first, InputIterator last, const T& val);
find和insert可以相互配合使用。
1.通过find找到位置插入
2.找到位置后插入n个val的值
3.找到位置后插入迭代器的区间
void testlist5()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
auto pos = find(lt.begin(), lt.end(), 3);
// 1.在pos之前插入一个值
if (pos != lt.end())
lt.insert(pos, 30); //insert以后pos没有失效
for (const auto& e : lt)
cout << e << " ";
cout << endl;
cout << *pos << endl;
// 2.插入n个数据
pos = find(lt.begin(), lt.end(), 3);
if (pos != lt.end())
lt.insert(pos, 4, 10);
for (const auto& e : lt)
cout << e << " ";
cout << endl;
// 3.插入一个迭代器区间
vector<int> v(5, 20);
pos = find(lt.begin(), lt.end(), 10);
if (pos != lt.end())
lt.insert(pos, v.begin(), v.end());
for (const auto& e : lt)
cout << e << " ";
cout << endl;
}
4.删除
void testlist6()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
auto pos = find(lt.begin(), lt.end(), 3);
if (pos != lt.end())
lt.erase(pos);
for (auto e : lt)
cout << e << " ";
cout << endl;
pos = find(lt.begin(), lt.end(), 4);
if (pos != lt.end())
lt.erase(pos, lt.end());
for (auto e : lt)
cout << e << " ";
cout << endl;
}
注意:对于list的insert的pos位置不会失效,在这个地方,只是在pos位置前增加节点,改变链接,pos位置并不会变成野指针。
五、其他成员函数
1.排序和去重
- sort
算法库有一个sort函数,但是list自己实现了,因为算法库的sort不能排序list:
算法库里的sort对于物理空间是连续的,只有vector和string能够使用,而对于list来说,物理空间并不是连续的,并不适用,所以list自己提供了一个sort进行排序,此外,链表的排序是归并排序。
void testlist7()
{
list<int> lt;
lt.push_back(12);
lt.push_back(1);
lt.push_back(6);
lt.push_back(9);
lt.push_back(4);
lt.push_back(8);
lt.push_back(10);
for (auto e : lt)
cout << e << " ";
cout << endl;
lt.sort();
for (auto e : lt)
cout << e << " ";
cout << endl;
}
- unique
对于unique:用来删除链表中连续的重复元素,但是注意:一定是要先排完序在进行删除,如果没有进行排序:而直接进行去重的话,会导致去重去不完全
void testlist8()
{
list<int> lt;
lt.push_back(12);
lt.push_back(9);
lt.push_back(1);
lt.push_back(12);
lt.push_back(12);
lt.push_back(9);
lt.push_back(8);
lt.push_back(9);
lt.push_back(12);
lt.unique();
for (auto e : lt)
cout << e << " ";
cout << endl;
lt.sort();
lt.unique();
for (auto e : lt)
cout << e << " ";
cout << endl;
}
2.splice和remove
- splice
void testlist9()
{
//转移到某个位置
list<int> lt1(5, 10);
list<int> lt2(4, 7);
lt1.splice(lt1.begin(), lt2);
for (auto e : lt1)
cout << e << " ";
cout << endl;
//从某个位置转移
list<int> lt3(4, 10);
list<int> lt4(4, 5);
lt3.splice(lt3.begin(), lt4, lt4.begin());
for (auto e : lt3)
cout << e << " ";
cout << endl;
//迭代器区间转移
list<int>lt5(3, 10);
list<int>lt6(3, 20);
lt5.splice(lt5.begin(), lt6, lt6.begin(), lt6.end());
for (auto e : lt5)
cout << e << " ";
cout << endl;
}
- remove
remove可以直接删除list中指定的数据
void testlist10()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
lt.push_back(1);
lt.push_back(1);
lt.remove(3);
for (auto e : lt)
cout << e << " ";
cout << endl;
lt.remove(1);
for (auto e : lt)
cout << e << " ";
cout << endl;
}
3.resize
list的resize很少用
void testlist11()
{
list<int> lt(5, 10);
lt.resize(3);
for (auto e : lt)
cout << e << " ";
cout << endl;
lt.resize(5);
for (auto e : lt)
cout << e << " ";
cout << endl;
lt.resize(7, 10);
for (auto e : lt)
cout << e << " ";
cout << endl;
}