C++之list容器

简介: C++之list容器

一、概念

list容器使用双链表实现;双链表将每个元素存储在不同的位置,每个节点通过next,prev指针链接成顺序表。

优点:

采用动态存储分配,不会造成内存浪费和溢出;

链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素;

缺点:

链表灵活,但是空间(指针域)和 时间 (遍历)额外耗费较大;

二、构造函数

void printList(const list<int> &l) {
    for (list<int>::const_iterator it = l.begin(); it != l.end(); it++) {
        cout << *it << " ";
    }
    cout << endl;
}
 
//list容器构造函数
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);
    // 10个100构造
    list<int> l3(10, 100);
    printList(l3);
    //拷贝构造函数
    list<int> l4(l3);
    printList(l4);
}


三、赋值和交换

 
//list赋值和交换
void test02() {
    //默认构造
    list<int> l1;
    // 添加数据
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    // 10 20 30 40
    printList(l1);
    list<int> l2;
    // 区间拷贝赋值
    l2.assign(l1.begin(), l1.end());
    // 10 20 30 40
    printList(l2);
 
    list<int> l3;
    // 10个100赋值
    l3.assign(10, 100);
    // 100 100 100 100 100 100 100 100 100 100
    printList(l3);
 
    list<int> l4;
    // 重载等号
    l4 = l3;
    // 100 100 100 100 100 100 100 100 100 100
    printList(l4);
 
    l4.swap(l1);
    cout << "交换后的l1和l4" << endl;
    printList(l1);
    printList(l4);
 
}

四、大小操作

//list容器大小操作
void test03() {
    //默认构造
    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 << "容器为空" << endl;
    } else {
        cout << "容器不为空" << endl;
    }
    // 获取容器大小
    cout << "容器的大小:" << l1.size() << endl;
    // 修改容器大小,如果扩容,使用100填充
    l1.resize(6, 100);
    printList(l1);
    l1.resize(3);
    printList(l1);
}

五、插入和删除

//list容器插入和删除
void test04() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    // 10 20 30 40
    printList(l1);
    // 尾删
    l1.pop_back();
    // 10 20 30
    printList(l1);
    // 头插
    l1.push_front(1000);
    // 1000 10 20 30
    printList(l1);
    // 头删
    l1.pop_front();
    // 10 20 30
    printList(l1);
    // 指定位置插入
    l1.insert(l1.begin(), 100);
    // 指定位置插入n个元素
    // 1000 1000 100 10 20 30
    l1.insert(l1.begin(), 2, 1000);
    printList(l1);
 
    list<int> l2;
    l2.push_back(101);
    l2.push_back(102);
    l2.push_back(103);
    l2.push_back(104);
    // 在开始位置,插入l2区间元素
    l1.insert(l1.begin(), l2.begin(), l2.end());
    // 101 102 103 104 1000 1000 100 10 20 30
    printList(l1);
    // 删除元素中所有1000这个值的元素
    l1.remove(1000);
    // 101 102 103 104 100 10 20 30
    printList(l1);
    // 删除第一位置的元素
    l1.erase(l1.begin());
    // 删除所有元素
    l1.erase(l1.begin(), l1.end());
    // 清空元素
    l1.clear();
}

六、数据存取

//list容器数据存取 不支持at []
void test05() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    printList(l1);
    // 获取第一个元素
    cout << l1.front() << endl;
    // 获取最后一个元素
    cout << l1.back() << endl;
    cout << l1.size() << endl;
 
    list<int>::iterator it = l1.begin();
    // 支持双向
    it++;
    it--;
    // it=it+1; //不支持最忌访问
}

七、反转和排序

 
// 降序
bool myCompare(int v1, int v2) {
    // 降序 让第一个数大于第二个数
    return v1 > v2;
}
 
//list容器反转和排序
void test06() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(60);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    cout << "list原始数据" << endl;
    printList(l1);
    l1.reverse();
    cout << "list容器反转" << endl;
    printList(l1);
    // 所有不支持随机访问迭代器的容器,不可以使用标准算法
    // sort(l1.begin(),l1.end());
    // 不支持随机访问迭代器的容器,内部回提供对应的一些算法
    l1.sort(); //默认升序
    cout << "排序后的list" << endl;
    printList(l1);
    cout << "降序排列" << endl;
    l1.sort(myCompare);
    printList(l1);
}

八、自定义数据类型排序

//自定义数据类型排序
class Person {
public:
    Person(string name, int age, int height) {
        this->m_Name = name;
        this->m_Age = age;
        this->m_Height = height;
    }
 
    string m_Name;
    int m_Age;
    int m_Height;
 
};
 
// 排序规则  按照年龄进行升序,如果年龄相同按照身高进行降序
bool myPersonCompaer(Person &p1, Person &p2) {
    if (p1.m_Age != p2.m_Age) {
        return p1.m_Age < p2.m_Age;
    } else {
        return p1.m_Height > p2.m_Height;
    }
}
 
//按照年龄进行升序,如果年龄相同按照身高进行降序
void test07() {
    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);
    cout << "排序前:" << endl;
    for (list<Person>::iterator it = l.begin(); it != l.end(); it++) {
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << " 身高:" << (*it).m_Height << endl;
    }
    l.sort(myPersonCompaer);
    cout << "排序后:" << endl;
    for (list<Person>::iterator it = l.begin(); it != l.end(); it++) {
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << " 身高:" << (*it).m_Height << endl;
    }
}

九、全部代码

#include <iostream>
#include<list>
#include <string>
 
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;
}
 
//list容器构造函数
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);
    // 10个100构造
    list<int> l3(10, 100);
    printList(l3);
    //拷贝构造函数
    list<int> l4(l3);
    printList(l4);
}
 
//list赋值和交换
void test02() {
    //默认构造
    list<int> l1;
    // 添加数据
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    // 10 20 30 40
    printList(l1);
    list<int> l2;
    // 区间拷贝赋值
    l2.assign(l1.begin(), l1.end());
    // 10 20 30 40
    printList(l2);
 
    list<int> l3;
    // 10个100赋值
    l3.assign(10, 100);
    // 100 100 100 100 100 100 100 100 100 100
    printList(l3);
 
    list<int> l4;
    // 重载等号
    l4 = l3;
    // 100 100 100 100 100 100 100 100 100 100
    printList(l4);
 
    l4.swap(l1);
    cout << "交换后的l1和l4" << endl;
    printList(l1);
    printList(l4);
 
}
 
//list容器大小操作
void test03() {
    //默认构造
    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 << "容器为空" << endl;
    } else {
        cout << "容器不为空" << endl;
    }
    // 获取容器大小
    cout << "容器的大小:" << l1.size() << endl;
    // 修改容器大小,如果扩容,使用100填充
    l1.resize(6, 100);
    printList(l1);
    l1.resize(3);
    printList(l1);
}
 
//list容器插入和删除
void test04() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    // 10 20 30 40
    printList(l1);
    // 尾删
    l1.pop_back();
    // 10 20 30
    printList(l1);
    // 头插
    l1.push_front(1000);
    // 1000 10 20 30
    printList(l1);
    // 头删
    l1.pop_front();
    // 10 20 30
    printList(l1);
    // 指定位置插入
    l1.insert(l1.begin(), 100);
    // 指定位置插入n个元素
    // 1000 1000 100 10 20 30
    l1.insert(l1.begin(), 2, 1000);
    printList(l1);
 
    list<int> l2;
    l2.push_back(101);
    l2.push_back(102);
    l2.push_back(103);
    l2.push_back(104);
    // 在开始位置,插入l2区间元素
    l1.insert(l1.begin(), l2.begin(), l2.end());
    // 101 102 103 104 1000 1000 100 10 20 30
    printList(l1);
    // 删除元素中所有1000这个值的元素
    l1.remove(1000);
    // 101 102 103 104 100 10 20 30
    printList(l1);
    // 删除第一位置的元素
    l1.erase(l1.begin());
    // 删除所有元素
    l1.erase(l1.begin(), l1.end());
    // 清空元素
    l1.clear();
}
 
//list容器数据存取 不支持at []
void test05() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(10);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    printList(l1);
    // 获取第一个元素
    cout << l1.front() << endl;
    // 获取最后一个元素
    cout << l1.back() << endl;
    cout << l1.size() << endl;
 
    list<int>::iterator it = l1.begin();
    // 支持双向
    it++;
    it--;
    // it=it+1; //不支持最忌访问
}
 
// 降序
bool myCompare(int v1, int v2) {
    // 降序 让第一个数大于第二个数
    return v1 > v2;
}
 
//list容器反转和排序
void test06() {
    //默认构造
    list<int> l1;
    // 尾插
    l1.push_back(60);
    l1.push_back(20);
    l1.push_back(30);
    l1.push_back(40);
    cout << "list原始数据" << endl;
    printList(l1);
    l1.reverse();
    cout << "list容器反转" << endl;
    printList(l1);
    // 所有不支持随机访问迭代器的容器,不可以使用标准算法
    // sort(l1.begin(),l1.end());
    // 不支持随机访问迭代器的容器,内部回提供对应的一些算法
    l1.sort(); //默认升序
    cout << "排序后的list" << endl;
    printList(l1);
    cout << "降序排列" << endl;
    l1.sort(myCompare);
    printList(l1);
}
 
//自定义数据类型排序
class Person {
public:
    Person(string name, int age, int height) {
        this->m_Name = name;
        this->m_Age = age;
        this->m_Height = height;
    }
 
    string m_Name;
    int m_Age;
    int m_Height;
 
};
 
// 排序规则  按照年龄进行升序,如果年龄相同按照身高进行降序
bool myPersonCompaer(Person &p1, Person &p2) {
    if (p1.m_Age != p2.m_Age) {
        return p1.m_Age < p2.m_Age;
    } else {
        return p1.m_Height > p2.m_Height;
    }
}
 
//按照年龄进行升序,如果年龄相同按照身高进行降序
void test07() {
    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);
    cout << "排序前:" << endl;
    for (list<Person>::iterator it = l.begin(); it != l.end(); it++) {
        cout << "姓名:" << (*it).m_Name << " 年龄:" << (*it).m_Age << " 身高:" << (*it).m_Height << endl;
    }
    l.sort(myPersonCompaer);
    cout << "排序后:" << endl;
    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();
    // test02();
    // test03();
    // test04();
    // test05();
    // test06();
    test07();
    system("pause");
    return 0;
}
 
排序前:
姓名:刘备 年龄:35 身高:175
姓名:曹操 年龄:45 身高:180
姓名:孙权 年龄:40 身高:170
姓名:赵云 年龄:25 身高:190
姓名:张飞 年龄:35 身高:160
姓名:关羽 年龄:35 身高:200
排序后:
姓名:赵云 年龄:25 身高:190
姓名:关羽 年龄:35 身高:200
姓名:刘备 年龄:35 身高:175
姓名:张飞 年龄:35 身高:160
姓名:孙权 年龄:40 身高:170
姓名:曹操 年龄:45 身高:180

相关文章
|
26天前
|
编译器 C语言 C++
【c++丨STL】list模拟实现(附源码)
本文介绍了如何模拟实现C++中的`list`容器。`list`底层采用双向带头循环链表结构,相较于`vector`和`string`更为复杂。文章首先回顾了`list`的基本结构和常用接口,然后详细讲解了节点、迭代器及容器的实现过程。 最终,通过这些步骤,我们成功模拟实现了`list`容器的功能。文章最后提供了完整的代码实现,并简要总结了实现过程中的关键点。 如果你对双向链表或`list`的底层实现感兴趣,建议先掌握相关基础知识后再阅读本文,以便更好地理解内容。
32 1
|
1月前
|
算法 C语言 C++
【c++丨STL】list的使用
本文介绍了STL容器`list`的使用方法及其主要功能。`list`是一种双向链表结构,适用于频繁的插入和删除操作。文章详细讲解了`list`的构造函数、析构函数、赋值重载、迭代器、容量接口、元素访问接口、增删查改操作以及一些特有的操作接口如`splice`、`remove_if`、`unique`、`merge`、`sort`和`reverse`。通过示例代码,读者可以更好地理解如何使用这些接口。最后,作者总结了`list`的特点和适用场景,并预告了后续关于`list`模拟实现的文章。
55 7
|
1月前
|
存储 编译器 C++
C++ initializer_list&&类型推导
在 C++ 中,`initializer_list` 提供了一种方便的方式来初始化容器和传递参数,而右值引用则是实现高效资源管理和移动语义的关键特性。尽管在实际应用中 `initializer_list&&` 并不常见,但理解其类型推导和使用方式有助于深入掌握现代 C++ 的高级特性。
24 4
|
3月前
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
83 2
|
2月前
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
49 0
|
3月前
|
存储 算法 C++
【C++打怪之路Lv10】-- list
【C++打怪之路Lv10】-- list
29 1
|
3月前
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
82 5
|
3月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
97 2
|
3月前
|
存储 缓存 C++
C++番外篇——list与vector的比较
C++番外篇——list与vector的比较
35 0
|
3月前
|
C++
C++番外篇——list的实现
C++番外篇——list的实现
28 0

热门文章

最新文章