网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
}
### size函数
**返回list中有效节点的个数。**
#include
#include
using namespace std;
int main()
{
list l1(5,3);
cout << l1.size() << endl;//5
}
### resize函数
**扩容并且初始化。**
resize函数和之前的string类和vector类函数的resize函数规则差不多:
* 当所给值大于当前的size时,将size扩大到该值,并且将扩大的数据初始化为第二个参数所给值,若未给出,则默认为容器所存储类型的默认构造函数所构造出来的值;
* 当所给值小于当前的size时,将size缩小到该值。
#include
#include
using namespace std;
int main()
{
list l1(2, 6);
for (auto e : l1)
{
cout << e << " ";
}
cout << endl; //6 6
l1.resize(4, 8); //将size扩大到4并且将扩大的值初始化为8
for (auto e : l1)
{
cout << e << " ";
}
cout << endl; //6 6 8 8
l1.resize(2); //将size缩到2
for (auto e : l1)
{
cout << e << " ";
}
cout << endl; //6 6
return 0;
}
## 插入和删除操作
| 函数声明 | 接口说明 |
| --- | --- |
| **push\_back** | **尾插** |
| **push\_front** | **头插** |
| **pop\_front** | **头删** |
| **pop\_back** | **尾删** |
| **insert** | **在指定的迭代器位置或区间插入数据** |
| **erase** | **删除指定迭代器位置或迭代器区间的数据** |
| swap | 交换两个list中的元素 |
| **clear** | **清除list中的所有元素** |
### push\_back和pop\_back
push\_back是尾插,pop\_back尾删。
使用:
下面的代码功能是依次在list尾部插入数据 1 2 3 4 5 6 7,插入完成之后打印;
打印之后再从尾部删除数据7 和 6:
#include
#include
using namespace std;
int main()
{
list l1;
for (int i = 1; i < 8; i++)
{
l1.push_back(i);
}
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//1 2 3 4 5 6 7
l1.pop_back();
l1.pop_back();
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//1 2 3 4 5
}
### push\_front和pop\_front
**头插和头删。**
使用:
#include
#include
using namespace std;
int main()
{
list l1;
for (int i = 1; i < 8; i++)
{
l1.push_front(i);
}
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//7 6 5 4 3 2 1
l1.pop_front();
l1.pop_front();
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
// 5 4 3 2 1
}
### insert函数
//在指定的迭代器位置插入数据
iterator insert (iterator position, const value_type& val);
//在指定的迭代器位置插入n个val值
void insert (iterator position, size_type n, const value_type& val);
//在指定迭代器位置插入一段迭代器区间(左闭右开)
template
void insert (iterator position, InputIterator first, InputIterator last);
**在指定的迭代器位置插入数据**
iterator insert (iterator position, const value_type& val);
使用:
#include
#include
using namespace std;
int main()
{
list l1;
l1.push_back(0);
auto it = l1.begin();
l1.insert(it, 100);//在头部插入值100
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出100 0
}
**在指定的迭代器位置插入n个val值**
void insert (iterator position, size_type n, const value_type& val);
使用:
#include
#include
using namespace std;
int main()
{
list l1;
l1.push_back(0);
auto it = l1.begin();
l1.insert(it,3, 100);//在头部插入3个值为100的数据
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出100 100 100 0
}
**在指定迭代器位置插入一段迭代器区间**
凡是和迭代器相关的基本上都是左闭右开。
#include
#include
using namespace std;
int main()
{
list l1;
list l2(4, 5);
auto it = l1.begin();
l1.insert(it,l2.begin(),l2.end());//在头部插入l2的begin到end的数据,左闭右开
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出5 5 5 5
}
### erase函数
//删除指定迭代器位置的值
iterator erase (iterator position);
//删除指定迭代器区间的值
iterator erase (iterator first, iterator last);
使用:
#include
#include
using namespace std;
int main()
{
list l1;
for (int i = 1; i < 8; i++)
{
l1.push_front(i);
}
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出7 6 5 4 3 2 1
// 删除指定迭代器位置
//删除数据5
auto it = find(l1.begin(), l1.end(), 5);//使用find函数查找
l1.erase(it);
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出7 6 4 3 2 1
//删除指定迭代器区间
//删除从6到2之间的数据,左闭右开,所以要找到指向数据1的迭代器
auto it1 = find(l1.begin(), l1.end(), 6);
auto it2 = find(l1.begin(), l1.end(), 1);
l1.erase(it1,it2);
for (auto e : l1)
{
cout << e << " ";
}
cout << endl;
//输出7 1
}
前面说过,此处大家可将迭代器暂时理解成类似于指针,**迭代器失效即迭代器所指向的节点的无效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭代器,其他迭代器不会受到影响**。
**所以erase()函数执行后,所指向的节点已被删除,迭代器失效,所以在下一次使用时,必须先给其赋值。**
### swap函数
**交换两个list中的元素**
void swap (list& x);
使用:
#include
#include
using namespace std;
int main()
{
list l1(2,6);
list l2(4, 5);
//遍历l1
for (auto e : l1)
{
cout << e << " ";
}
//输出6 6
cout << endl;
//遍历l2
for (auto e : l2)
{
cout << e << " ";
}
//输出5 5 5 5
cout << endl;
l1.swap(l2);//交换l1和l2
//遍历l1
for (auto e : l1)
{
cout << e << " ";
}
//输出5 5 5 5
cout << endl;
//遍历l2
for (auto e : l2)
{
cout << e << " ";
}
//输出6 6
cout << endl;
}
### clear函数
**清除list中的所有元素**
void clear();
使用:
#include
#include
using namespace std;
int main()
{
list l1(2,6);
//遍历l1
for (auto e : l1)
{
cout << e << " ";
}
//输出6 6
l1.clear();//清除l1中元素
for (auto e : l1)
{
cout << e << " ";
}
//什么也不输出
}
## 迭代器
**我们可以将迭代器理解成指针,指向list中的某个节点。**
| 函数声明 | 接口说明 |
| --- | --- |
| begin + end | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
| rbegin + rend | 返回第一个元素的reverse\_iterator,即end位置,返回最后一个元素下一个位置的 reverse\_iterator,即begin位置 |
**迭代器都是左闭右开**
### begin和end函数
使用:
#include
#include
#include
using namespace std;
int main()
{
list l1;
for (int i = 0; i < 5; i++)
{
l1.push_back(i);
}
//正向迭代器的使用
//正向遍历
list::iterator it = l1.begin();
while (it != l1.end())//遍历
{
cout << *it << " ";
it++;
}
//输出 0 1 2 3 4
cout << endl;
}
### rbegin和rend函数
#include
#include
#include
using namespace std;
int main()
{
list l1;
for (int i = 0; i < 5; i++)
{
l1.push_back(i);
}
//反向迭代器的使用
//反向遍历
list::reverse_iterator rit = l1.rbegin();
while (rit != l1.rend())
{
cout << *rit << " ";
rit++;
}
//输出 4 3 2 1 0
cout << endl;
}
## 元素获取
| 函数声明 | 接口说明 |
| --- | --- |
| front | 返回list的第一个节点中值的引用 |
| back | 返回list的最后一个节点中值的引用 |
### front函数
**front函数用于获取list容器当中的第一个元素的引用(能够修改元素)。**
使用:
#include
#include
using namespace std;
int main()
{
list l1(2,6);
//遍历l1
for (auto e : l1)
{
cout << e << " ";
}
//输出6 6
cout << l1.front() << endl;//获取第一个元素,输出6
l1.front() = 100; //获取第一个元素并将第一个元素改为100
for (auto e : l1)
{
cout << e << " ";
}
//输出100 6
}
### back函数
**back函数用于获取list容器当中的最后一个元素(能够修改元素)。**
使用:
#include
#include
using namespace std;
int main()
{
list l1(2,6);
//遍历l1
for (auto e : l1)
{
cout << e << " ";
}
//输出6 6
cout << l1.back() << endl;//获取最后一个元素,输出6
l1.back() = 100; //获取最后一个元素并将其改为100
for (auto e : l1)
{
cout << e << " ";
}
//输出 6 100
}
## 操作函数
| 函数声明 | 接口说明 |
| --- | --- |
| sort | 将容器当中的数据默认排为升序 |
| remove | 删除容器中指定值的元素 |
| remove\_if | 删除容器中满足条件的元素 |
| unique | 删除容器当中连续的重复元素 |
| reverse | 将容器当中元素的位置进行翻转逆置 |
| assign | 新内容分配给容器替换容器当前内容 |
| splice | 两个list容器之间的拼接 |
### sort函数
算法库中的sort函数代码如下:是通过指针相减算出来的,而list容器不是连续的地址所以这种算法对于list来说并不适用。
![image-20230701160438900](https://img-blog.csdnimg.cn/img_convert/a6158664bcc90c87f62252c91fd0990b.png)
list容器中的sort函数使用的是归并排序,算法库中的sort使用的是快排,快排是三个数取中间数同样不适用list。
从功能上来说迭代器要分三类:
1.单向迭代器 ++
2.双向迭代器(list) ++ –
3.随机迭代器(vector string) ++ – + -
在函数使用的时候如果模板中是双向不能使用单向,如果是单向可以传随机和双向。
算法库中的sort函数迭代器要传随机迭代器:
![image-20230701160750349](https://img-blog.csdnimg.cn/img_convert/252abe66294d835970dd9b3aa91aa468.png)
sort函数使用:
#include
#include
using namespace std;
int main()
{
list l1;
//遍历l1
for (int i = 13; i >= 3; i–)
{
l1.push_back(i);
}
//输出6 6
for (auto e : l1)
{
cout << e << " ";
}
//输出13 12 11 10 9 8 7 6 5 4 3
l1.sort();
for (auto e : l1)
{
cout << e << " ";
}
//输出 3 4 5 6 7 8 9 10 11 12 13
}
但是在实际中我们很少使用list的sort排序,因为性能不行。
比较vector和list容器的sort排序时间:
#include
#include
#include
#include
using namespace std;
int main()
{
//list和vector的sort函数性能测试
srand(time(nullptr));
list<int> l1;
vector<int> v1;
const int N = 1000000;
v1.reserve(N);
for (int i = 0; i < N; i++)
{
auto e = rand();//随机数
v1.push\_back(e);//插入
l1.push\_back(e);//插入
}
int begin1 = clock();
sort(v1.begin(), v1.end());
int end1 = clock();
int begin2 = clock();
l1.sort();
int end2 = clock();
cout << "vector sort:" << (end1 - begin1) << endl;//vector排序时间
cout << "list sort:" << (end2 - begin2) << endl;//list排序时间
在release下进行测试:
![image-20230701162113993](https://img-blog.csdnimg.cn/img_convert/3eaab984e644475d2f5e975ae6bfea5d.png)
我们再尝试先将list容器中的数据放在vector中,然后再排序,排完序之后再放到list容器中:
#include
#include
#include
#include
using namespace std;
int main()
{
//list和vector的sort函数性能测试
srand(time(nullptr));
list<int> l1;
vector<int> v1;
const int N = 1000000;
v1.reserve(N);
for (int i = 0; i < N; i++)
{
auto e = rand();//随机数
v1.push\_back(e);//插入
l1.push\_back(e);//插入
}
//vector排序时间
int begin1 = clock();
sort(v1.begin(), v1.end());
int end1 = clock();
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
include
#include
#include
#include
using namespace std;
int main()
{
//list和vector的sort函数性能测试
srand(time(nullptr));
list<int> l1;
vector<int> v1;
const int N = 1000000;
v1.reserve(N);
for (int i = 0; i < N; i++)
{
auto e = rand();//随机数
v1.push\_back(e);//插入
l1.push\_back(e);//插入
}
//vector排序时间
int begin1 = clock();
sort(v1.begin(), v1.end());
int end1 = clock();
[外链图片转存中…(img-iXiOcccU-1715556045410)]
[外链图片转存中…(img-Rune09yp-1715556045411)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!