文章目录
- 前情回顾
- list
- 概念
- 优缺点
- 构造函数
- 赋值函数
- 交换函数
- 容器和大小操作
- 插入操作
- 删除操作
- 单个数据访问
- 反转操作
- 排序
- 下一座石碑
🎉welcome🎉
✒️博主介绍:一名大一的智能制造专业学生,在学习C/C++的路上会越走越远,后面不定期更新有关C/C++语法,数据结构,算法,Linux,ue5使用,制作游戏的心得,和大家一起共同成长。
✈️C++专栏:C++爬塔日记
😘博客制作不易,👍点赞+⭐收藏+➕关注
前情回顾
在上一块石碑中,我学到了queue,同时下一块石碑也显露出来…
- 🚄上章地址:第九章(6):STL之queue
list
概念
- list可以将数据链式存储,list也就是链表,链表是由一系列的节点组成,节点是内部有两块区域,一个是存放下一个节点地址的指针域,一个是存放数据的数据域,链表可以对任意位置进行快速的插入和删除,但是因为链表不是一块连续的空间,所以遍历的速度慢于数组,并且占用空间比数组要大,list的本质就是一个双向循环链表,双向循环列表指的就是,第一个节点记录着最后的位置,最后一个节点记录第一个节点的位置
- 由于链表的储存方法不是连续空间,所以list的迭代器只支持前移和后移,属于双向迭代器,不能随机访问
优缺点
- 优点:
- 采用动态存储分配,不会造成内存的浪费和溢出
- list的插入和删除十分方便,只需要修改指针就可以,不需要移动内部的大量数据
- list的插入和删除不会造成原有的迭代器失效,而vector不行,因为vector在插入扩展的时候,会找一片新空间将数据拷贝过去,
- 缺点:
- 相比较数组而言,链表所占用的空间较大,遍历消耗的额外时间较多
构造函数
- list中的构造函数与vector一样,有四个构造函数
list< T >;//;默认构造函数
list(beg,end);//将迭代器beg到end之间的数据拷贝到本身
list(size_t n,T elem);//将n个elem赋值给本身
list(const list &l);//将l的元素拷贝到本身
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
list<int> l1(10, 1);
print(l1);
list<int>l2(l1);
print(l2);
list <int>l3(l1.begin(), l1.end());
print(l3);
}
int main()
{
test1();
return 0;
}
赋值函数
- list中的赋值操作与vector中也是一样的,有三种
list& operator=(const list &l);//操作符重载
assign(beg,end);//将迭代器beg到end的数据拷贝到本身
assign(int n,T elem);//将n个elem拷贝到本身
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l(10, 1);
print(l);
list<int> l1;
l1 = l;
print(l1);
list<int> l2;
l2.assign(l1.begin(),l1.end());
print(l2);
list<int> l3;
l3.assign(10, 2);
print(l3);
}
int main()
{
test1();
return 0;
}
交换函数
- 与vector一样,可以利用swap函数进行交换
swap(list< T > &l);//将l的数据和本身进行交换
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
cout << "交换前" << endl;
list<int> l(10, 1);
print(l);
list<int> l1;
l1.assign(10, 2);
print(l1);
cout << "交换后" << endl;
l.swap(l1);
print(l);
print(l1);
}
int main()
{
test1();
return 0;
}
容器和大小操作
- list比vector少一个容器大小,因为list的空间不是连续的,数据存放方式也与vector不同,有多少元素大小就多少,和vector不一样,所以不需要
size();//返回容器内元素个数
empty();//判断容器是否为空,为空返回真
resize(size_t num);///可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补0,若变短,则将超出的部分全部删除
reszie(size_t num,T elem);//可以重新指定容器的容量,容量为num,若容器变长,则变长的部分全部补elem,若变短,则将超出的部分全部删除
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
if (l.empty())
{
cout << "l为空" << endl;
}
cout << l.size() << endl;
l.assign(10, 1);
print(l);
l.resize(11);
print(l);
l.resize(15, 1);
print(l);
}
int main()
{
test1();
return 0;
}
插入操作
- list中,有五种插入操作,可以从头部插入,从尾部插入,还有insert的三个重载版本
push_front(T elem);//在头部插入elem
push_end(T elem);//在尾部插入elem
insert(pos,T elem);//在pos的位置插入一个elem,返回新数据的位置
insert(pos, size_t n,T elem);//在pos位置插入n个elem
insert(pos,beg,end);//在pos位置插入迭代器beg到end的数据
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
l.push_back(2);
print(l);
l.push_front(1);
print(l);
l.insert(l.end(), 3);
print(l);
l.insert(l.begin(), 1,0);
print(l);
list<int>::iterator b = l.begin();
b++;
l.insert(b, l.begin(), l.end());
print(l);
}
int main()
{
test1();
return 0;
}
删除操作
- 删除操作有六个,向比较vector多了头部的删除,和一个删除一样元素的删除
pop_back();//删除尾部元素
pop_front();//删除头部元素
clear();//删除全部元素
erase(beg,end);//删除迭代器beg到end之间的数据
erase(pos);//删除迭代器pos位置的数据,返回下一个元素的位置
remove(T elem);//删除容器中所有的elem
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
for (int i = 0; i < 10; i++)
{
l.push_back(i);
l.push_back(i);
}
print(l);
l.pop_back();
print(l);
l.pop_front();
print(l);
list<int>::iterator b = l.begin();
b++; b++; b++;
l.erase(b);
print(l);
list<int>::iterator b1 = l.begin();
b1++; b1++; b1++;
l.erase(b1, l.end());
print(l);
l.remove(1);
print(l);
l.clear();
print(l);
}
int main()
{
test1();
return 0;
}
单个数据访问
- 因为在list中空间不是连续的,同时,list的迭代器也不支持随机访问,所以对于list来说[ ]和at是不适用于list的,可以利用迭代器++或者–来访问其他元素
front();//返回第一个元素
back();//返回最后一个元素
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
for (int i = 0; i < 10; i++)
{
l.push_back(i);
}
print(l);
cout << l.front() << endl;
cout << l.back() << endl;
}
int main()
{
test1();
return 0;
}
反转操作
- 在list中可以反转链表,就是让链表中所有元素交换位置,后面的与前面的交换。
reverse();//反转链表
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
for (int i = 0; i < 10; i++)
{
l.push_back(i);
}
cout << "反转前" << endl;
print(l);
cout << "反转后" << endl;
l.reverse();
print(l);
}
int main()
{
test1();
return 0;
}
排序
- 在容器当中,可以使用一个算法函数来对容器内的数据进行一个排序,默认从小到大,但是是对于支持随机访问的迭代器,可以使用标准算法,对于list这种不支持随机访问的迭代器,是不可以用标准算法的,只能用类内的算法
sort();//排序
使用:
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
void test1()
{
list<int> l;
for (int i = 9; i >=0; i--)
{
l.push_back(i);
}
print(l);
l.sort();
print(l);
}
int main()
{
test1();
return 0;
}
- 那想从大到小排呢?这个时候需要一个函数,函数返回类型为bool,内部可以让传参的两个参数进行比较,任何前者大于后者,返回真,如果小于返回假,返回假就会进行交换
#include<iostream>
#include<list>
using namespace std;
void print(list<int>& l)
{
for (list<int>::iterator b=l.begin(); b != l.end(); b++)
{
cout << *b << " ";
}
cout << endl;
}
bool com(int a, int b)
{
return a > b;//可以简化成这样,返回的是a>b的结果,如果结果是对的,不进行交换,如果不对,进行交换
}
void test1()
{
list<int> l;
for (int i = 0; i < 10; i++)
{
l.push_back(i);
}
print(l);
l.sort(com);
print(l);
}
int main()
{
test1();
return 0;
}
下一座石碑
- 这座石碑倒下了,露出了下一座石碑…
😘预知后事如何,关注新专栏,和我一起征服C++这座巨塔
🚀专栏:C++爬塔日记
🙉都看到这里了,留下你们的👍点赞+⭐收藏+📋评论吧🙉