list双向链表

STL中list是一个双向循环列表:

使用list时需要包含头文件<list>

#include <list>

list对象自带两个指针,分别指向第一个元素和最后一个元素;

list不支持随机访问。访问中间元素需要遍历,时间复杂度为O(n);访问头部与尾部元素时间复杂度为O(1);

list在任意位置进行插入和删除操作,时间复杂度为O(1);

定义与初始化

初始化 含义
list<T> l1 l1 是一个存放 T 类型数据的空 list
list<T> l2(l1) 利用 l1 构造 l2,l2 包含 l1 的所有数据
list<T> l2 = l1 同上
list<T> l3(n, val) l3 包含 n 个 val
list<T> l4(n) l4 包含 n 个默认 T 类型的数据
list<T> l5{a, b, c, ...} l5 包含初始化列表提供的数据
list<T> l5 = {a, b, c, ...} 同上

void Show(const list<int>& l)
{
    for (auto x : l)
        cout << x << " ";
    cout << endl;
}

int main()
{
    list<int> l1;          //空链表
    list<int> l2(2);       //包含两个默认元素值的链表
    list<int> l3(3, 4);     //包含3个4的链表
    list<int> l4{ 1,2,3,4 }; //包含1,2,3,4的链表
    list<int> l5(14);      //把14的值赋值给l5

    cout << "l1:";  Show(l1);
    cout << "l2:";  Show(l2);
    cout << "l3:";  Show(l3);
    cout << "l4:";  Show(l4);
    cout << "l5:";  Show(l5);

    return 0;
}

list常用迭代器

list支持双向迭代器。

list迭代器不是随机迭代器,不能 +- 数字。可以 ++--

list迭代器不能比较大小。可以 ==!=

迭代器 含义
l.begin() 第一个元素的迭代器
l.end() 最后一个元素的下一个位置迭代器
l.cbegin() 第一个元素的常量迭代器
l.cend() 尾后常量迭代器
l.rbegin() 从后往前的第一个迭代器
l.rend() 从后往前的最后一个迭代器
l.crbegin() 从后往前的第一个常量迭代器
l.crend() 从后往前的最后一个常量迭代器
int main()
{
    list<int> l{ 1, 2, 3, 4, 5 };

    //从头到尾输出链表元素
    cout << "从头到尾输出:";
    for (list<int>::const_iterator it = l.cbegin(); it != l.cend(); ++it)
        cout << *it << " ";
    cout << endl;

    //把所有元素值+10
    cout << "所有元素值+10:";
    for (auto it = l.begin(); it != l.end(); ++it)
    {
        *it += 10;
        cout << *it << " ";
    }
    cout << endl;
        
    //从尾到头输出链表元素
    cout << "从尾到头输出:";
    for (auto it = l.crbegin(); it != l.crend(); ++it)
        cout << *it << " ";
    cout << endl;

    return 0;
}

list常用运算符

运算符 含义
l2 = l1 把 l1 的数据赋值给 l2
l1 == l2 判断是否相等
l1 != l2 判断是否不相等
<, <=, >, >= 判断大小关系,从头到尾依次比较
不支持[]
int main()
{
    list<int> l1{ 1,2,3,4,5,6 };
    list<int> l2;

    l2 = l1;//把l1的元素赋值给l2
    cout << "l1:"; Show(l1);//输出l1
    cout << "l2:"; Show(l2);//输出l2

    if (l1 == l2)
        cout << "l1 == l2" << endl;

    l1.front() = 100;//把l1的第一元素改为100
    cout << "l1:"; Show(l1);//输出l1
    cout << "l2:"; Show(l2);//输出l2

    if (l1 != l2)
        cout << "l1 != l2" << endl;

    if (l1 > l2)
        cout << "l1 > l2" << endl;
    else
        cout << "l1 <= l2" << endl;

    return 0;
}

list常用成员函数

成员函数 含义 成员函数 含义
l.empty() 判断是否为空 l.push_back() 尾插
l.size() 返回 l 的数据个数 l.pop_back() 尾删
l.front() 返回第一个元素的引用 l.insert() 插入一个或多个元素
l.push_front() 头插 l.erase() 删除一个或多个元素
l.pop_front() 头删 l.swap() 交换两个 list 的值
l.back() 返回最后一个元素的引用 l.clear() 清空数据

empty成员函数

判断list对象是否为空

size成员函数

获取list对象数据个数

int main()
{
    list<int> l1;
    if (l1.empty())//判空
        cout << "l1是空的,数据个数=" << l1.size() << endl;

    l1.assign({ 1,2,3,4,5 });
    if (!l1.empty())
    {
        cout << "l1:"; Show(l1);
        cout << "l1不是空的,数据个数=" << l1.size() << endl;
    }

    return 0;
}

front成员函数

获取第一个元素的引用

push_front成员函数

从头部插入数据

pop_front成员函数

从头部删除数据

int main()
{
    list<int> l1{ 1,2,3 };

    l1.push_front(10);//头插
    l1.push_front(20);
    l1.push_front(30);

    while (!l1.empty())
    {
        cout << l1.front() << " ";//输出l1的第一个元素
        l1.pop_front();//删除第一个元素
    }
    cout << endl;

    return 0;
}

back成员函数

获取最后一个元素的引用

push_back成员函数

尾部插入数据,可以自动扩容

pop_back成员函数

尾部删除数据

int main()
{
    list<int> l2{ 10,20,30 };

    l2.push_back(40);//尾插
    l2.push_back(50);
    l2.push_back(60);

    while (!l2.empty())
    {
        cout << l2.back() << " ";//输出l2的最后元素
        l2.pop_back();//删除最后一个元素
    }
    cout << endl;

    return 0;
}

insert成员函数

插入一个或多个元素,时间复杂度为O(1)

int main()
{
    list <int> l1{ 1, 2, 3 };
    list <int> l2{ 4, 5, 6 };
    list <int>::iterator Iter;
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    Iter = l1.begin();
    l1.insert(Iter, 100);//在开始位置插入数字100
    cout << "l1:"; Show(l1);

    Iter = l1.begin();
    Iter++;
    l1.insert(Iter, 2, 200);//在Iter位置插入2个100
    cout << "l1:"; Show(l1);

    //在l1的begin后面插入l2的所有元素,不包含l2的最后一个
    l1.insert(++l1.begin(), l2.begin(), --l2.end());
    cout << "l1:"; Show(l1);

    l2.insert(l2.begin(), { 10,20,30 });//插入多个元素
    cout << "l2:"; Show(l2);

    return 0;
}

erase成员函数

删除一个或多个元素

int main()
{
    list<int> l1{ 1,2,3,4,5,6 };
    cout << "l1:"; Show(l1);

    l1.erase(l1.begin()); //删除一个元素
    cout << "l1:"; Show(l1);

    l1.erase(l1.begin(), l1.end());//删除多个元素
    cout << "l1:"; Show(l1);

    return 0;
}

swap成员函数

交换两个list的值

int main()
{
    list<int> l1{ 1,2,3,4 };
    list<int> l2{ 5,6,7,8,9,10,11,12 };
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    l1.swap(l2);//交换两个链表

    cout << "交换后..." << endl;
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    return 0;
}

clear成员函数

清空数据

int main()
{
    list<int> l1{ 1,2,3,4,5 };
    cout << "l1:"; Show(l1);
    l1.clear();
    cout << "清空后" << endl;
    cout << "l1:"; Show(l1);

    return 0;
}

list特有成员函数

成员函数 含义
l.merge() 链表合并
l.remove(val) 删除所有和val相同的元素
l.remove_if() 删除符合条件的元素
l.reverse() 反转链表中的元素
l.sort() 排序(默认为升序)
l.splice() 链表连结
l.unique() 删除重复元素

merge特有成员函数

把两个链表的元素进行合并。

合并的前提:是原本两个链表必须按照合并的方法有序。

默认升序合并。

int main()
{
    list <int> l1{ 3, 4, 6 };
    list <int> l2{ 2, 5, 7 };
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    l2.merge(l1);  //把l1合并到l2中,默认升序,前提l1,l2必须升序有序
    cout << "合并l1后" << endl;
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);
    cout << endl;

    list <int> l3{ 20, 15, 12,11 };
    list <int> l4{ 22, 15, 10 };
    cout << "l3:"; Show(l3);
    cout << "l4:"; Show(l4);

    l4.merge(l3, greater<int>());//按降序合并,前提l3,l4必须降序有序
    cout << "合并l3后" << endl;
    cout << "l3:"; Show(l3);
    cout << "l4:"; Show(l4);

    return 0;
}

remove特有成员函数

删除所有和_vel相同的值

int main()
{
    list<int> l1{ 1, 2, 1, 2, 3, 1, 2, 3, 4 };
    cout << "l1:"; Show(l1);

    l1.remove(1);//删除所有值为1的元素
    cout << "删除1后,";
    cout << "l1:"; Show(l1);

    return 0;
}

remove_if特有成员函数

删除符合条件的元素

template <class T> class is_odd
{
public:
    bool operator( ) (T& val)
    {
        return (val % 2) == 1;//奇数
    }
};//奇数函数对象

int main()
{
    list <int> l1{ 1,2,3,4,5,6,7,8 };
    cout << "l1:"; Show(l1);

    l1.remove_if(is_odd<int>());//删除值为奇数的元素
    cout << "删除奇数后,";
    cout << "l1:"; Show(l1);

    return 0;
}

reverse特有成员函数

将所有元素反序

int main()
{
    list <int> l1{1,2,3,4,5,6,7,8,9,10};
    cout << "l1:"; Show(l1);

    l1.reverse();
    cout << "反序后" << endl;
    cout << "l1:"; Show(l1);

    return 0;
}

sort特有成员函数

默认升序排序,可以提供排序依据

int main()
{
    list <int> l1{7,2,3,1,4,9,8,6,5};
    cout << "l1:"; Show(l1);

    l1.sort();//默认升序
    cout << "排序后,";
    cout << "l1:"; Show(l1);

    l1.sort(greater<int>());//降序
    cout << "降序排序后,";
    cout << "l1:"; Show(l1);

    return 0;
}

splice特有成员函数

链表连结:把一个链表的元素连结到另一个链表中。

它和merge的区别是:merge要求数据必须有序,而splice对数据没有要求。

int main()
{
    list<int> l1{ 10, 11 };
    list<int> l2{ 20, 21, 22 };
    //把l2连结在l1的第二个位置
    l1.splice(++l1.begin(), l2);
    Show(l1);

    list<int> l3{ 30, 31 };
    list<int> l4{ 40, 41, 42, 43 };
    //把l4连结在l3的最后面
    l3.splice(l3.end(), l4);
    Show(l3);

    return 0;
}

unique特有成员函数

删除相邻且重复的值,只保留一个

重复的值如果不相邻,不会删除

int main() {
    list <int> l1{1,1,2,2,4,4,3,3,3,3,0};
    list <int> l2{-1,1,1,3,3,3,5,5,-1};

    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    cout << "删除过相邻且相同的数字后" << endl;
    l1.unique();
    l2.unique();
    cout << "l1:"; Show(l1);
    cout << "l2:"; Show(l2);

    return 0;
}

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐