C++提高编程---3.7 STL-常用容器-list 容器【P215~P222】
-
- [3.7 list 容器](#3.7 list 容器)
-
- [3.7.1 list 容器基本概念](#3.7.1 list 容器基本概念)
- [3.7.2 list 构造函数](#3.7.2 list 构造函数)
- [3.7.3 list 赋值和交换](#3.7.3 list 赋值和交换)
- [3.7.4 list 大小操作](#3.7.4 list 大小操作)
- [3.7.5 list 插入和删除](#3.7.5 list 插入和删除)
- [3.7.6 list 数据存取](#3.7.6 list 数据存取)
- [3.7.7 list 反转和排序](#3.7.7 list 反转和排序)
- [3.7.8 排序案例](#3.7.8 排序案例)
3.7 list 容器
3.7.1 list 容器基本概念
功能: 将数据进行链式存储
链表(list) 是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的
链表的组成: 链表由一系列结点组成
结点的组成: 一个是存储数据元素 的数据域,另一个是存储下一个结点地址 的指针域;
优点: 可以对任意位置进行快速插入和删除元素;
缺点: 遍历速度没有数组快,占用的空间比数组大(每个节点还有指针域);

由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器

3.7.2 list 构造函数

cpp
#include<iostream>
#include<list>
using namespace std;
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);
L1.push_back(50);
// 遍历容器
printList(L1);
// 区间方式构造
list<int>L2(L1.begin(), L1.end());
printList(L2);
// 拷贝构造
list<int>L3(L2);
printList(L3);
// n个element
list<int>L4(5, 100);
printList(L4);
}
int main() {
test01();
system("pause");
return 0;
}

总结:list构造方式其他几个STL常用容器,熟练掌握即可
3.7.3 list 赋值和交换

cpp
#include<iostream>
#include<list>
using namespace std;
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);
L1.push_back(50);
// 遍历容器
printList(L1);
list<int>L2;
L2 = L1;
printList(L2);
list<int>L3;
L3.assign(L2.begin(), L2.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);
L1.push_back(50);
list<int>L2;
L2.assign(10, 100);
cout << "交换前:" << endl;
printList(L1);
printList(L2);
swap(L1, L2);
//L1.swap(L2); // 两种交换方式都可以
cout << "交换后:" << endl;
printList(L1);
printList(L2);
}
int main() {
cout << "赋值测试:" << endl;
test01();
cout << "交换测试:" << endl;
test02();
system("pause");
return 0;
}

3.7.4 list 大小操作

cpp
#include<iostream>
#include<list>
using namespace std;
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);
L1.push_back(50);
// 遍历容器
printList(L1);
// 判断是否为空
if (L1.empty())
cout << "L1 为空" << endl;
else {
cout << "L1 不为空" << endl;
cout << "L1 的元素个数为:" << L1.size() << endl;
}
// 重新指定大小
L1.resize(10);
printList(L1);
L1.resize(3);
printList(L1);
}
int main() {
test01();
system("pause");
return 0;
}

3.7.5 list 插入和删除

cpp
#include<iostream>
#include<list>
using namespace std;
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);
L1.push_back(50);
printList(L1);
// 头插
L1.push_front(60);
L1.push_front(70);
L1.push_front(80);
L1.push_front(90);
L1.push_front(100);
printList(L1);
// 尾删
L1.pop_back();
printList(L1);
// 头删
L1.pop_front();
printList(L1);
// insert 插入
L1.insert(L1.begin(), 1000);
printList(L1);
// 迭代器访问
list<int>::iterator it = L1.begin();
L1.insert(++it, 2000);
printList(L1);
// 删除
it = L1.begin();
L1.erase(it);
printList(L1);
// 移除所有指定元素
L1.push_back(60);
L1.push_back(60);
L1.push_back(60);
L1.push_back(60);
L1.push_back(60);
printList(L1);
L1.remove(60);
printList(L1);
// 清空
L1.clear();
printList(L1);
}
int main() {
cout << "两端操作" << endl;
test01();
system("pause");
return 0;
}

3.7.6 list 数据存取

cpp
#include<iostream>
#include<list>
using namespace std;
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);
L1.push_back(50);
printList(L1);
cout << "第一个元素为:" << L1.front() << endl;
cout << "最后一个元素为:" << L1.back() << endl;
list<int>::iterator it = L1.begin();
cout << *++it << endl; // 这样访问可以
//cout << *(it+2) << endl; // 随机访问不可以,因为内存不连续
}
int main() {
cout << "两端操作" << endl;
test01();
system("pause");
return 0;
}

3.7.7 list 反转和排序

cpp
#include<iostream>
#include<list>
using namespace std;
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);
cout << endl << "排序前:" << endl;
printList(L1);
// 排序
L1.sort();
cout << "排序后:" << endl;
printList(L1);
// 不支持随机访问迭代器的容器,不可以使用标准算法,比如 algorithm 中的 sort()
}
int main() {
cout << "两端操作" << endl;
test01();
system("pause");
return 0;
}

3.7.8 排序案例

cpp
#include<iostream>
#include<list>
#include<string>
using namespace std;
class Person {
public:
Person(string name, int age, int tall) {
this->name_ = name;
this->age_ = age;
this->tall_ = tall;
}
string name_;
int age_;
int tall_;
};
// 排序规则
bool comparePerson(Person &p1, Person &p2) {
// 年龄相同的话按照身高降序
if (p1.age_ == p2.age_)
return p1.tall_ > p2.tall_;
else // 年龄不相同的话按照年龄升序
return p1.age_ < p2.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->name_ << " 年龄:" << it->age_ << " 身高:" << it->tall_ << endl;
}
// 按照年龄升序
L.sort(comparePerson);
cout << endl << "排序后:" << endl;
for (list<Person>::iterator it = L.begin(); it != L.end(); it++) {
cout << "姓名:" << it->name_ << " 年龄:" << it->age_ << " 身高:" << it->tall_ << endl;
}
}
int main() {
cout << "两端操作" << endl;
test01();
system("pause");
return 0;
}
