在完成对C语言的学习后,我最近开始了对C++和Java的学习,目前跟着视频学习了一些语法,也跟着敲了一些代码,有了一定的掌握程度。现在将跟着视频做的笔记进行整理。本篇博客是整理C++知识点的第二十六篇博客。
本篇博客介绍了C++的list容器。
本系列博客所有C++代码都在Visual Studio 2022环境下编译运行。程序为64位。
目录
list容器
list基本概念
list将数据进行链式存储。
链表是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表的指针链接实现的。链表由一系列结点组成,结点包括本身数据元素以及存储下一个结点地址的指针。
STL的list是一个双向循环链表。
链表的存储方式不是连续的内存空间,因此链表list的迭代器(list<T>::iterator)只能用++和--(前置后置均可)。
list采用动态存储分配,不会造成内存浪费和溢出。list执行插入和删除很方便,但是遍历比较慢。
list插入和删除不会造成原有迭代器的失效,在vector中是不成立的。
list和vector各有优缺点,确定选用哪个容器应该综合考虑。
list构造函数
使用list需要包含头文件list。
list<T> lst创建一个list容器,存储T类型数据。
list(beg,end)将beg到end区间的元素(包括beg不包括end)拷贝给本身。
list(n,elem)将n个elem拷贝给本身。
list(const list &lst)是拷贝构造函数。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
l1.push_back(50);
for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int>l2(l1);
for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int>l3(l1.begin(), l1.end());
for (list<int>::iterator it = l3.begin(); it != l3.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int>l4(10, 20);
for (list<int>::iterator it = l4.begin(); it != l4.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
程序的输出是:
10 20 30 40 50
10 20 30 40 50
10 20 30 40 50
20 20 20 20 20 20 20 20 20 20
list赋值和交换
assign(beg,end)将beg到end(包括beg不包括end)的数据拷贝给本身。
assign(n,elem)将n个elem拷贝赋值给本身。
list& operator=(const list &lst)重载等号操作符。
swap(lst)将lst与本身元素互换。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l1;
l1.push_back(10);
l1.push_back(20);
l1.push_back(30);
l1.push_back(40);
l1.push_back(50);
for (list<int>::iterator it = l1.begin(); it != l1.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int> l2;
l2 = l1;
for (list<int>::iterator it = l2.begin(); it != l2.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int> l3;
l3.assign(l2.begin(), l2.end());
for (list<int>::iterator it = l3.begin(); it != l3.end(); it++) {
cout << *it << " ";
}
cout << endl;
list<int> l4;
l4.assign(5, 10);
for (list<int>::iterator it = l4.begin(); it != l4.end(); it++) {
cout << *it << " ";
}
cout << endl;
l3.swap(l4);
for (list<int>::iterator it = l3.begin(); it != l3.end(); it++) {
cout << *it << " ";
}
cout << endl;
for (list<int>::iterator it = l4.begin(); it != l4.end(); it++) {
cout << *it << " ";
}
cout << endl;
return 0;
}
程序的输出是:
10 20 30 40 50
10 20 30 40 50
10 20 30 40 50
10 10 10 10 10
10 10 10 10 10
10 20 30 40 50
list大小操作
size()返回容器中元素个数。
empty()判断容器是否为空。
resize(num)重新指定容器长度为num,如果容器变长,就以默认值填充新位置。如果容器变短就删除超出容器长度的元素。
resize(num,elem)重新指定容器长度为num,如果容器变长,就以elem填充新元素。如果容器变短就删除超出容器长度的元素。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l;
l.push_back(10);
l.push_back(20);
l.push_back(30);
l.push_back(40);
l.push_back(50);
cout << l.empty() << endl;
cout << l.size() << endl;
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.resize(10);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.resize(15, 20);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.resize(5);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
程序的输出是:
0
5
10 20 30 40 50
10 20 30 40 50 0 0 0 0 0
10 20 30 40 50 0 0 0 0 0 20 20 20 20 20
10 20 30 40 50
list插入和删除
push_back(elem)将elem加入容器尾部。
pop_back()删除最后一个元素。
push_front(elem)将elem加入容器头部。
pop_front()删除第一个元素。
insert(pos,elem)在pos位置插入elem。
insert(pos,n,elem)在pos位置插入n个elem。
insert(pos,beg,end)在pos位置插入beg到end的数据,包括beg不包括end。
clear()清除容器的所有数据。
erase(beg,end)删除beg到end的数据,包括beg不包括end。
erase(pos)删除pos位置数据。
remove(elem)删除容器中所有与elem值匹配的元素。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l;
l.push_back(10);
l.push_back(20);
l.push_back(30);
l.push_back(40);
l.push_front(100);
l.push_front(200);
l.push_front(300);
l.push_front(400);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.pop_back();
l.pop_front();
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.insert(++l.begin(), 20);
l.insert(++(++(++l.begin())), 3, 50);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.erase(++(++l.begin()));
l.remove(20);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
程序的输出是:
400 300 200 100 10 20 30 40
300 200 100 10 20 30
300 20 200 50 50 50 100 10 20 30
300 50 50 50 100 10 30
list数据存取
front()返回第一个元素。
back()返回最后一个元素。
list不能用下标和at访问。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l;
l.push_back(10);
l.push_back(20);
l.push_back(30);
l.push_front(15);
l.push_front(25);
l.push_front(35);
l.push_front(45);
cout << l.front() << endl;
cout << l.back() << endl;
return 0;
}
程序的输出是:
45
30
list反转和排序
reverse()反转链表。
sort()进行链表排序。默认从小到大。
不支持随机访问迭代器的容器(如list)不可以用标准算法。
#include<iostream>
#include<list>
using namespace std;
int main(void)
{
list<int> l;
l.push_back(75);
l.push_back(65);
l.push_back(45);
l.push_back(95);
l.push_back(35);
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.reverse();
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
l.sort();
for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
cout << *it << " ";
}
cout << endl;
return 0;
}
程序的输出是:
75 65 45 95 35
35 95 45 65 75
35 45 65 75 95
对于自定义数据类型,排序时要指定排序规则。
#include<iostream>
#include<list>
#include<string>
using namespace std;
class person
{
public:
string name;
int age;
int height;
person(){}
person(string name, int age, int height) {
this->name = name;
this->age = age;
this->height = height;
}
};
bool compare(person& p1, person& p2)
{
if (p1.age != p2.age) {
return p1.age > p2.age;
}
else {
return p1.height > p2.height;
}
}
int main(void)
{
person p1("Jimena", 19, 190);
person p2("Julia", 18, 160);
person p3("Jose", 17, 180);
person p4("Jeanne", 18, 180);
person p5("John", 22, 160);
list<person> l;
l.push_back(p1);
l.push_back(p2);
l.push_back(p3);
l.push_back(p4);
l.push_back(p5);
for (list<person>::iterator it = l.begin(); it != l.end(); ++it) {
cout << "The name is " << it->name << " and the age is " << it->age << " and the height is " << it->height << endl;
}
cout << endl;
l.sort(compare);
for (list<person>::iterator it = l.begin(); it != l.end(); ++it) {
cout << "The name is " << it->name << " and the age is " << it->age << " and the height is " << it->height << endl;
}
return 0;
}
程序创建了person类,有name age和height三个成员变量。compare函数接受两个person类对象,先比较age再比较height,结果是降序排序。main函数创建了一个list类型容器l,存储person类对象,并加入五个类对象。进行排序时将compare函数名作为参数传入。
程序的输出是:
The name is Jimena and the age is 19 and the height is 190
The name is Julia and the age is 18 and the height is 160
The name is Jose and the age is 17 and the height is 180
The name is Jeanne and the age is 18 and the height is 180
The name is John and the age is 22 and the height is 160
The name is John and the age is 22 and the height is 160
The name is Jimena and the age is 19 and the height is 190
The name is Jeanne and the age is 18 and the height is 180
The name is Julia and the age is 18 and the height is 160
The name is Jose and the age is 17 and the height is 180