写在前面:⭐如果本篇博文对你有帮助,那就 点赞 + 关注 + 收藏 一下吧!

目录

1.list基本概念

2.list构造函数

3.list赋值和交换

4.list大小操作

5.list插入和删除

6.list数据存取

7.list反转和排序

8.排序案例


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;
}

总结:
        ●对于自定义数据类型,必须要指定排序规则,否则编译器不知道如何进行排序
        ●高级排序只是在排序规则上再进行一次逻辑规则制定,并不复杂

写到后面:⭐如果本篇博文对你有帮助,那就 点赞 + 关注 + 收藏一下吧!

更多推荐