C++ STL常用容器6——list容器
写在前面:⭐如果本篇博文对你有帮助,那就 点赞 + 关注 + 收藏 一下吧!
目录
1.list基本概念
功能:将数据进行链式存储
链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。
链表的组成:链表由一系列结点组成
结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域
STL中的链表是一个双向循环链表

链表:
优点:可以对任意位置进行快速插入或聊除余元素
缺点:容器遍历速度,没有数组快;占用空间比数组大

由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器。
list的优点:
●采用动态存储分配,不会造成内存浪费和溢出。
●链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素。
list的缺点:
●链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大
List有一个重要的性质,插入操作和删除操作都不会造成原有list迭代器的失效,这在vector是不成立的。
总结:STL中List和vector是两个最常被使用的容器,各有优缺点。
2.list构造函数
功能描述:创建list容器
示例:
#include <iostream>
using namespace std;
#include <list>
//list构造函数
void printList(const list<int>&l)
{
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
//创建list容器
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
//遍历容器
printList(l1);
//区间方式构造
list<int> l2(l1.begin(),l1.end());
printList(l2);
//拷贝构造
list<int> l3(l2);
printList(l3);
//n个elem方式构造
list<int> l4(10,100);
printList(l4);
}
int main()
{
test01();
return 0;
}
总结:list构造方式同其他几个STL常用容器,熟练掌握即可
3.list赋值和交换
功能描述:
●给list容器进行赋值,以及交换list容器

示例:
#include <iostream>
using namespace std;
#include <list>
//list赋值和交换
void printList(const list<int> &l)
{
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//赋值
void test01()
{
list<int>l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
printList(l1);
list<int>l2;
l2 = l1; // operator= 方式赋值
printList(l2);
list<int>l3;
l3.assign(l1.begin(),l1.end());
printList(l3);
list<int>l4;
l4.assign(10,100);
printList(l4);
}
//交换
void test02()
{
list<int>l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
list<int>l2;
l2.assign(10,100); // 10个100
cout << "交换前:" << endl;
cout << "l1: " ;
printList(l1);
cout << "l2: " ;
printList(l2);
l1.swap(l2);
cout << "交换后:" << endl;
cout << "l1: " ;
printList(l1);
cout << "l2: " ;
printList(l2);
}
int main()
{
//test01();
test02();
return 0;
}
/*
交换前:
l1: 10 20 30 40
l2: 100 100 100 100 100 100 100 100 100 100
交换后:
l1: 100 100 100 100 100 100 100 100 100 100
l2: 10 20 30 40
*/
总结:list赋值和交换操作能够灵活运用即可
4.list大小操作
功能描述:
●对list容器的大小进行操作

示例:
#include <iostream>
using namespace std;
#include <list>
//list容器大小操作
void printList(const list<int> &l)
{
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
list<int>l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
printList(l1);
//判断容器是否为空
if (l1.empty())
{
cout << "l1为空" << endl;
}
else
{
cout << "l1不为空" << endl;
}
cout << "l1的容量为:" << l1.size() << endl;
//重新指定大小
//l1.resize(10); // 10 20 30 40 0 0 0 0 0 0
l1.resize(10,100); // 10 20 30 40 100 100 100 100 100 100
printList(l1);
cout << "l1的容量为:" << l1.size() << endl;
l1.resize(2);
printList(l1); //10 20
}
int main()
{
test01();
return 0;
}
总结:
●判断是否为空 —— empty
●返回元素个数 —— size
●重新指定个数 —— resize
5.list插入和删除
功能描述:
●对list容器进行数据的插入和制除

示例:
#include <iostream>
using namespace std;
#include <list>
//list插入和删除
void printList(const list<int> &l)
{
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
void test01()
{
list<int>l1;
//尾插
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
//头插
l1.push_front(100);
l1.push_front(200);
l1.push_front(300);
printList(l1); //300 200 100 10 20 30
//尾删
l1.pop_back();
printList(l1); //300 200 100 10 20
//头删
l1.pop_front();
printList(l1); //200 100 10 20
//insert插入
list<int>::iterator it = l1.begin();
l1.insert(++it,1000);
printList(l1); // 200 1000 100 10 20 30
//删除
it = l1.begin();
l1.erase(it);
printList(l1); //1000 100 10 20 30
//移除
l1.push_back(10000);
l1.push_back(10000);
l1.remove(10000);
printList(l1); //1000 100 10 20 30
//清空
l1.clear();
printList(l1);
}
int main()
{
test01();
return 0;
}
总结:
●尾插 —— push_back
●尾删 —— pop_back
●头插 —— push_front
●头删 —— pop_front
●插入 —— insert
●删除 —— erase
●移除 —— remove
●清空 —— lear
6.list数据存取
功能描述:
●对list容器中数据进行存取
函数原型:
●front( ); //返回第一个元素。
●back( ); //返回最后一个元素。
示例:
#include <iostream>
using namespace std;
#include <list>
//list数据存取
void test01()
{
list<int>l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
//l1[0] 不可以用[]访问list容器中的元素
//l1.at(0) 不可以用at访问list容器中的元素
//原因:list容器本质是链表,不是用连续的线性空间存储数据,迭代器也是不支持随机访问的
cout << "第一个元素为:" << l1.front() << endl; //10
cout << "最后一个元素为:" << l1.back() << endl; //40
//验证迭代器是不支持随机访问的
list<int>::iterator it = l1.begin();
it++; //支持双向
it--;
//it += 1; //不支持随机访问
}
int main()
{
test01();
return 0;
}

总结:
●list容器中不可以通过[ ]或者at方式访问数据
●返回第一个元素 —— front
●返回最后一个元素 —— back
7.list反转和排序
功能描述:
●将容器中的元素反转,以及将容器中的数据进行排序
函数原型:
●reverse(); //反转链表
●sort(); //链表排序
示例:
#include <iostream>
using namespace std;
#include <list>
//list反转和排序
void printList(const list<int> &l)
{
for (list<int>::const_iterator it = l.begin(); it != l.end(); it++)
{
cout << *it << " ";
}
cout << endl;
}
//反转
void test01()
{
list<int>l1;
l1.push_back(20);
l1.push_back(10);
l1.push_back(50);
l1.push_back(40);
l1.push_back(30);
cout << "反转前:" << endl;
printList(l1);
//反转
l1.reverse();
cout << "反转后:" << endl;
printList(l1);
}
bool myCompare(int v1,int v2)
{
return v1 > v2;
}
//排序
void test02()
{
//反转
list<int>l1;
l1.push_back(20);
l1.push_back(10);
l1.push_back(50);
l1.push_back(40);
l1.push_back(30);
cout << "排序前:" << endl;
printList(l1);
//排序
//所有不支持随机访问迭代器得容器,不可以用标准算法
//不支持随机访问迭代器的容器,内部会提供一些对应的算法
//sort(l1.begin(),l1.end());
l1.sort(); //默认排序规则:升序
cout << "排序后:" << endl;
printList(l1);
//降序
l1.sort(myCompare);
printList(l1);
}
int main()
{
test01();
test02();
return 0;
}
/*
排序前:
20 10 50 40 30
排序后:
10 20 30 40 50
50 40 30 20 10
*/
总结:
●反转 —— reverse
●排序 —— sort(成员函数)
8.排序案例
案例描述:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高
排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序
示例:
#include <iostream>
using namespace std;
#include <list>
//排序案例 对于自定义数据类型做排序
//案例描述:将Person自定义数据类型进行排序,Person中属性有姓名、年龄、身高
//排序规则:按照年龄进行升序,如果年龄相同按照身高进行降序
class Person
{
public:
Person(string name,int age,int height)
{
this ->m_Name = name;
this ->m_Age = age;
this ->m_Height = height;
}
//重载小于运算符
bool operator<(Person &p)
{
return this ->m_Age < p.m_Age;
}
//重载大于运算符
bool operator>(Person &p)
{
return this ->m_Age > p.m_Age;
}
string m_Name;
int m_Age;
int m_Height;
};
//指定排序规则
bool myCompare(Person &p1,Person &p2)
{
if (p1.m_Age == p2.m_Age)
{
return p1.m_Height > p2.m_Height;
}
else
{
return p1.m_Age < p2.m_Age;
}
}
void test01()
{
list<Person>l; //创建容器
//准备数据
Person p1("刘备",35,175);
Person p2("曹操",45,180);
Person p3("孙权",40,170);
Person p4("赵云",25,190);
Person p5("张飞",35,160);
Person p6("关羽",35,200);
//向容器中插入数据
l.push_back(p1);
l.push_back(p2);
l.push_back(p3);
l.push_back(p4);
l.push_back(p5);
l.push_back(p6);
for (list<Person>::iterator it = l.begin(); it != l.end(); it++)
{
cout << "姓名:" << it ->m_Name << " 年龄:" << it ->m_Age << " 身高:" << it ->m_Height << endl;
}
//排序
cout << "-------------------------" << endl;
cout << "排序后:" << endl;
l.sort(myCompare);
for (list<Person>::iterator it = l.begin(); it != l.end(); it++) {
cout << "姓名:" << it ->m_Name << " 年龄:" << it ->m_Age << " 身高:" << it ->m_Height << endl;
}
}
int main()
{
test01();
return 0;
}
总结:
●对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序
●高级排序只是在排序规则上再进行一次逻辑规则制定,并不复杂
写到后面:⭐如果本篇博文对你有帮助,那就 点赞 + 关注 + 收藏一下吧!
更多推荐
所有评论(0)