《C++ list 完全指南:从基础到高效使用》

《C++ list 完全指南:从基础到高效使用》


文章目录


一、forward_list和list比较



二、list的接口介绍

1.list的构造



2.list iterator的使用

迭代器可以理解成一个指针,该指针指向list中的某个节点!





3.list的容量操作

这里指介绍重要的接口,一些不重要的接口可以参考string和vector


resize的用法和string、vector几乎相同,这里不再过多赘述


4.list的访问操作





迭代器失效问题一会就会进行讲解!



5.list的其他操作接口


splice()函数主要用于在列表中进行元素的转移操作。
它可以将一个列表中的部分或全部元素转移到另一个列表中。
可以指定要转移的元素范围以及目标插入位置等,实现了高效灵活的元素移动和重组


remove函数相当于一直遍历列表,然后erase删除指定元素


remove_if 函数 相当于 remove 的补充,它支持传参函数或者仿函数


unique函数主要用于移除列表中相邻的重复元素。
他使得容器中只保留不重复的元素序列,
但需要注意:他并不保证取出所有重复元素,知识处理相邻的重复项,通常也需要结合其他操作


merge( )函数主要用于将两个已排序的序列合并成一个新的已排序序列
他会按照排序顺序将一个序列中的元素与另一个序列中的元素合理地组合在一起,形成一个合并后的有序序列

需要注意的是,在合并之前,两个源序列本身需要时已经排序好的


list中的sort( )函数用于对列表进行排序。他会按照指定的排序规则(默认是升序)对列表中的元素进行重新排列,使得元素按有序多的方式呈现!


reverse( )函数,用于实现list的逆置


三、list的迭代器失效




四、list与vector的对比



五、源代码总结

代码如下(示例):

c 复制代码
//#include <iostream>
//using namespace std;
//#include <forward_list>
//int main()
//{
//    forward_list<int> fl = { 1, 2, 3 };
//    // 在头部插入元素
//    fl.push_front(0);
//
//    // 遍历并输出
//    for (int num : fl)
//    {
//        cout << num << " ";
//    }
//    cout << endl;
//
//    return 0;
//}


#include <iostream>
#include <list>
using namespace std;
//int main()
//{
//    list<int> myList = { 10, 20, 30, 40, 50 };
//    // 在头部插入元素
//    myList.push_front(5);
//    // 在尾部插入元素
//    myList.push_back(60);
//    // 遍历并输出
//    for (int num : myList) {
//        cout << num << " ";
//    }
//    cout << endl;
//
//    // 删除指定元素
//    myList.remove(30);
//
//    // 再次遍历输出
//    for (int num : myList) {
//        cout << num << " ";
//    }
//    cout << endl;
//    return 0;
//}

void Test1()
{
    // 默认构造函数
    list<int> numbers1;
    cout << "默认构造: ";
    for (const auto& num : numbers1) {
        cout << num << " ";
    }
    cout << endl;
    // n个val构造
    list<int> numbers2(5, 10);
    cout << "n个val构造: ";
    for (const auto& num : numbers2) {
        cout << num << " ";
    }
    cout << endl;

    int arr[] = { 1, 2, 3 };
    // 通过vector的迭代器初始化
    list<int> numbers3(arr, arr + sizeof(arr) / sizeof(arr[0]));
    cout << "迭代器区间构造: ";
    for (const auto& num : numbers3) {
        cout << num << " ";
    }
    cout << endl;

    list<int> numbers4 = { 4, 5, 6 };
    // 拷贝构造
    list<int> numbers5(numbers4);
    cout << "拷贝构造: ";
    for (const auto& num : numbers5) {
        cout << num << " ";
    }
    cout << endl;

    numbers1 = numbers2;
    // 赋值重载
    cout << "赋值重载: ";
    for (const auto& num : numbers1) {
        cout << num << " ";
    }
    cout << endl;
}
void Test2()
{
    list<int> numbers = { 1, 2, 3, 4, 5 };
    list<int>::iterator it = numbers.begin();
    cout << "First element: " << *it << endl;
    while (it != numbers.end())
    {
        cout << *it << " ";
        ++it;
    }
    // 注意:这里不能直接解引用it,因为此时它指向的是头节点
    cout << endl;
}
void Test3()
{
    list<int> numbers = { 1, 2, 3, 4, 5 };
    list<int>::reverse_iterator rit = numbers.rbegin();
    cout << "Last element: " << *rit << endl;
    while (rit != numbers.rend())
    {
        cout << *rit << " ";
        ++rit;
    }
    cout << endl;
}
void Test4()
{
    list<int> numbers = { 1, 2, 3, 4, 5 };
    cout << "Size of list: " << numbers.size() << endl;
    cout << "Max size of list: " << numbers.max_size() << endl;
}


void Test5()
{
    list<int> numbers;
    if (numbers.empty())
    {
        cout << "List is empty" << endl;
    }
    numbers = { 1, 2, 3 };
    numbers.clear();
    if (numbers.empty())
    {
        cout << "List is cleared and now empty" << endl;
    }
}

void Test6()
{
    list<int> numbers = { 1, 2, 3 };
    numbers.resize(5);
    cout << "After resizing to 5: ";
    for (auto& num : numbers)
    {
        cout << num << " ";
    }
    cout << endl;

    numbers.resize(2);
    cout << "After resizing to 2: ";
    for (auto& num : numbers)
    {
        cout << num << " ";
    }
    cout << endl;
}
void Test7()
{
    list<int> myList = { 10, 20, 30 };  // 创建一个包含元素的列表

    // 输出列表的第一个元素
    cout << "The front element is: " << myList.front() << endl;

    // 输出列表的最后一个元素
    cout << "The back element is: " << myList.back() << endl;
}




void Test8()
{
    list<int> myList;  // 创建一个空列表

    myList.push_back(10);  // 在列表尾部添加元素 10
    myList.push_back(20);  // 在列表尾部添加元素 20

    cout << "列表元素: ";
    for (auto& num : myList) {
        cout << num << " ";
    }
    cout << endl;

    myList.pop_back();  // 删除列表尾部的元素

    cout << "删除尾部元素后列表元素: ";
    for (auto& num : myList) {
        cout << num << " ";
    }
    cout << endl;
}
void Test9()
{
    list<int> myList;  // 创建一个空列表
    myList.push_front(5);  // 在列表头部添加元素 5
    myList.push_front(3);  // 在列表头部添加元素 3
    cout << "列表元素: ";
    for (auto& num : myList) {
        cout << num << " ";
    }
    cout << endl;
    myList.pop_front();  // 删除列表头部的元素
    cout << "删除头部元素后列表元素: ";
    for (auto& num : myList)
    {
        cout << num << " ";
    }
    cout << endl;
}
void Test10()
{
    list<int> myList = { 1, 2, 3 };
    list<int>::iterator it = myList.begin();
    it = myList.insert(it, 4);  // 这里迭代器 it 失效
    it = myList.insert(it, 5);  // 这里迭代器 it 失效
    for (auto& num : myList)
    {
        cout << num << " ";
    }
    cout << endl;
}
void Test11()
{
    list<int> myList = { 1, 2, 3, 4, 5 };
    list<int>::iterator it = myList.begin();
    it = myList.erase(it);  // 迭代器 it 失效
    it = myList.erase(it);  // 迭代器 it 失效
    for (auto& num : myList)
    {
        cout << num << " ";
    }
    cout << endl;
}
void Test12()
{
    list<int> list1 = { 1, 2, 3 };
    list<int> list2 = { 4, 5, 6 };
    cout << "交换之前:" << endl;
    for (auto& num : list1)
    {
        cout << num << " ";
    }
    cout << endl;

    for (auto& num : list2)
    {
        cout << num << " ";
    }
    cout << endl;
    list1.swap(list2);
    cout << "交换之前:" << endl;
    for (auto& num : list1)
    {
        cout << num << " ";
    }
    cout << endl;

    for (auto& num : list2)
    {
        cout << num << " ";
    }
    cout << endl;

}
void Test13()
{
    list<int> list1 = { 1, 2, 3 };
    list<int> list2 = { 4, 5 };

    // 将 list2 的元素转移到 list1 中
    list1.splice(list1.end(), list2);

    for (auto num : list1) {
        cout << num << " ";
    }
    cout << endl;
}
void Test14()
{
    list<int> myList = { 1, 2, 2, 3, 2 };

    // 移除值为 2 的元素
    myList.remove(2);

    for (auto num : myList) {
        cout << num << " ";
    }
    cout << endl;
}
bool isEven(int num) {
    return num % 2 == 0;
}

void Test15() {
    list<int> myList = { 1, 2, 3, 4, 5, 6 };

    // 移除满足偶数条件的元素
    myList.remove_if(isEven);

    for (auto num : myList) {
        cout << num << " ";
    }
    cout << endl;
}
void Test16()
{
    list<int> myList = { 1, 2, 2, 3, 3, 3 };

    // 移除相邻的重复元素
    myList.unique();
    for (auto num : myList) {
        cout << num << " ";
    }
    cout << endl;
}
void Test17()
{
    list<int> list1 = { 1, 3, 5 };
    list<int> list2 = { 2, 4, 6 };

    list1.sort();
    list2.sort();

    // 合并两个已排序的列表
    list1.merge(list2);

    for (auto num : list1) {
        cout << num << " ";
    }
    cout << endl;
}
void Test18() {
    list<int> myList = { 3, 1, 4, 1, 5, 9, 2, 6, 5 };

    // 对列表进行排序
    myList.sort();

    for (auto num : myList) {
        cout << num << " ";
    }
    cout << endl;
}
void Test19()
{
    list<int> l2 = { 1,2,4,5 };
    l2.reverse();//list中的reverse
    reverse(l2.begin(), l2.end());//算法库中的reverse
    for (auto& num : l2)
    {
        cout << num << " ";
    }
}
void TestListIterator1()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        // erase()函数执行后,it所指向的节点已被删除,因此it无效,在下一次使用it时,必须先给
        //其赋值
            l.erase(it);
        ++it;
    }
}
// 改正
void TestListIterator()
{
    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    list<int> l(array, array + sizeof(array) / sizeof(array[0]));
    auto it = l.begin();
    while (it != l.end())
    {
        l.erase(it++); // it = l.erase(it);
    }
}

int main()
{
    //Test1();
    //Test2();
    //Test4();
    //Test5();
    //Test6();
    //Test7();
    //Test8();
    //Test9();
    //Test10();
    //Test11();
    //Test12();
    //Test13();
    //Test14();
    //Test15();
    //Test16();
    //Test17();
    //Test18();
    Test19();
}
相关推荐
励志不掉头发的内向程序员21 小时前
STL库——AVL树
开发语言·c++·学习
晨非辰1 天前
#C语言——刷题攻略:牛客编程入门训练(十一):攻克 循环控制(三),轻松拿捏!
c语言·开发语言·经验分享·学习·visual studio
励志码农1 天前
JavaWeb 30 天入门:第二十三天 —— 监听器(Listener)
java·开发语言·spring boot·学习·servlet
天高云淡ylz1 天前
子网掩码的隐形陷阱:为何能ping通却无法HTTPS访问
开发语言·php
奔跑吧 android1 天前
【linux kernel 常用数据结构和设计模式】【数据结构 2】【通过一个案例属性list、hlist、rbtree、xarray数据结构使用】
linux·数据结构·list·kernel·rbtree·hlist·xarray
汉克老师1 天前
第十四届蓝桥杯青少组C++选拔赛[2023.2.12]第二部分编程题(5、机甲战士)
c++·算法·蓝桥杯·01背包·蓝桥杯c++·c++蓝桥杯
希望20171 天前
Golang Panic & Throw & Map/Channel 并发笔记
开发语言·golang
朗迹 - 张伟1 天前
Golang安装笔记
开发语言·笔记·golang
yzx9910131 天前
生活在数字世界:一份人人都能看懂的网络安全生存指南
运维·开发语言·网络·人工智能·自动化
小周同学@1 天前
谈谈对this的理解
开发语言·前端·javascript