【C++容器篇之list】

553 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文已参与「掘力星计划」,赢取创作大礼包,挑战创作激励金。

list

概念

  • 链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针连接实现的

  • 链表的组成:链表是由一系列节点组成

  • 节点的组成:一个是存储数据元素的数据域,另一个是存储下一个节点地址指针域

  • STL中的链表是一个双向循环链表

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

优点

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

  • list的一个重要性质:插入和删除操作都不会造成原有list迭代器的失效,这在vector中式不成立的

小结

  • STLlistvector是两个最常被使用的容器,各有优缺点

list构造函数

【函数原型】:

- list<T> lst; // list采用模板类实现,对象的默认构造形式

- list<begin,end>; //拷贝构造函数,将区间[begin,end]中的元素拷贝给自身

- list(n,elem); // 构造函数将n个elem拷贝给自身

- list(const list &lst); //  拷贝构造函数

【demo】:

#include <iostream>
#include <list>

using namespace std;

void printList(const list<int> &lst)
{
    for (list<int>::const_iterator it = lst.begin(); it != lst.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);
    cout << "默认构造函数:" << endl;
    printList(l1);

    list<int> l2(l1.begin(), l1.end());
    cout << "拷贝[begin,end]区间的元素:" << endl;
    printList(l2);

    // 拷贝构造函数
    list<int> l3(l2);
    cout << "拷贝构造函数:" << endl;
    printList(l3);

    // 将10个1拷贝给自身
    list<int> l4(10, 1);
    cout << "将10个1拷贝给自身:" << endl;
    printList(l4);
}

int main()
{
    test01();
    return 0;
}

list赋值和交换

【函数原型】:

- assign(begin,end); // 将[begin,end]区间中的数据拷贝赋值给自身

- assign(n,elem); //将n个ele拷贝赋值为自身

- list &operator=(const list &list); // 重载等号操作符

- swap(lst); // 将lst与自身的元素互换

【demo】:

#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);

    cout << "L1:" << endl;
    printList(L1);

    list<int> L2;
    L2.assign(L1.begin(), L1.end());
    cout << "assign(begin,end); // 将[begin,end]区间中的数据拷贝赋值给自身 --> L2:" << endl;
    printList(L2);

    list<int> L3;
    L3.assign(10, 1);
    cout << "assign(n,elem); //将n个ele拷贝赋值为自身 --> L3:" << endl;
    printList(L3);

    list<int> L4 = L3;
    cout << "list &operator=(const list &list); // 重载等号操作符 --> L4:" << endl;
    printList(L4);

    L3.swap(L1);
    cout << "swap L1 and L3 :" << endl;
    cout << "L1:";
    printList(L1);
    cout << "L3:";
    printList(L3);
}
int main()
{
    test01();
    return 0;
}

list大小操作

【函数原型】:

- size(); // 返回容器中元素的个数

- empty(); // 判断容器是否为空

- resize(num); // 重新制定容器长度为num,若容器变长,则以默认值填充新位置,若容器变短,则末尾超出容器长度的部分将被删除

- resize(num,elem); // // 重新制定容器长度为num,若容器变长,则使用elem填充新位置,若容器变短,则末尾超出容器长度的部分将被删除

【demo】:

#include <iostream>
#include <list>

using namespace std;
void printList(const list<int> &L)
{
    if (!L.empty())
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << endl;
    }
    else
    {
        cout << "list is empty !" << endl;
    }
}

void test01()
{

    list<int> L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);

    printList(L1);

    cout << "L1.size() = " << L1.size() << endl;

    L1.resize(10);
    printList(L1);

    L1.resize(20, 5);
    printList(L1);
}

int main()
{
    test01();
    return 0;
}

list插入与删除

【函数原型】:

- push_back(elem); // 在容器尾部加入一个元素

- pop_back(); // 删除容器中最后一个元素

- push_front(); // 在容器开头插入一个元素

- pop_front(); // 删除容器开头的元素

- insert(pos,elem); // 在pos位置插入elem元素的拷贝,返回新数据的位置

- insert(pos,n,elem); // 在pos位置插入n个elem元素,无返回值

- insert(pos,begin,end); // 在pos位置插入[begin,end]区间的数据,无返回值

- clear(); // 清除所有数据

- erase(begin,end); // 删除[begin,end]区间内的数据,返回下一个数据的位置

- erase(pos); // 删除Pos位置的数据,返回下一个数据的位置

- remove(elem); // 删除容器中所有与elem匹配的元素

【demo】:

#include <iostream>
#include <list>
using namespace std;

void printList(const list<int> &L)
{
    if (L.empty())
    {
        cout << "L is empty ." << endl;
    }
    else
    {
        cout << "L : ";
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size:" << L.size() << 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);

    // 尾删
    L1.pop_back();
    // 头删
    L1.pop_front();
    printList(L1);

    list<int>::iterator it = L1.begin();
    // 头插
    L1.insert(++it, 1000);
    printList(L1);

    // 删除元素
    it = L1.begin();
    L1.erase(++it);
    printList(L1);

    //移除元素
    L1.push_back(66666);
    L1.push_back(88888);
    printList(L1);

    L1.remove(66666);
    printList(L1);

    L1.clear();
    printList(L1);
}

int main()
{
    test01();
    return 0;
}

小结

  • 尾插 push_back()

  • 尾删 pop_back()

  • 头插 push_front()

  • 头删 pop_front()

  • 插入 insert()

  • 删除 erase()

  • 移除 remove()

  • 清空 clear()

list数据存取

【函数原型】:

- front(); // 返回第一个元素

- back(); // 返回最后一个元素

【demo】:

#include <iostream>
#include <list>

using namespace std;

void printList(const list<int> &L)
{
    if (L.empty())
    {
        cout << "L is empty ." << endl;
    }
    else
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size:" << L.size() << endl;
    }
}

void test01()
{
    list<int> L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);

    cout << "first elem is : " << L1.front() << endl;
    cout << "last elem is : " << L1.back() << endl;
    // list 不支持 at,[]操作
    // list容器的迭代器是双向迭代器,不支持随机访问
    list<int>::iterator it = L1.begin();
    //it = it + 1; // 错误,不可以跳跃访问,即使是+1
}

int main()
{

    test01();
    return 0;
}

list反转与排序

【函数原型】:

- reverse(); //反转链表

- sort(); //链表排序

【demo】:

#include <iostream>
#include <list>
using namespace std;

void printList(const list<int> &L)
{
    if (L.empty())
    {
        cout << "L is empty ." << endl;
    }
    else
    {
        for (list<int>::const_iterator it = L.begin(); it != L.end(); it++)
        {
            cout << *it << " ";
        }
        cout << " , size:" << L.size() << endl;
    }
}

bool myCompare(int v1, int v2)
{
    return v1 > v2;
}

void test01()
{
    list<int> L1;
    L1.push_back(10);
    L1.push_back(20);
    L1.push_back(30);
    L1.push_back(40);
    printList(L1);

    // 反转容器中的元素
    L1.reverse();
    cout << "L1 after reverse : " << endl;
    printList(L1);

    // 默认排序
    L1.sort();
    cout << "L1 after default sort : " << endl;
    printList(L1);

    // 指定排序规则,从大到小
    L1.sort(myCompare);
    cout << "L1 after myCompare sort : " << endl;
    printList(L1);
}

int main()
{

    test01();
    return 0;
}