容器库(5)-std::list

std::forward_list是可以从任何位置快速插入和移除元素的容器,不支持快速随机访问,支持正向和反向的迭代。

本文章的代码库:

https://gitee.com/gamestorm577/CppStd

成员函数

构造、析构和赋值

构造函数

可以用元素、元素列表、迭代器或者另一个list来构造list。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec{1.1f, 2.1f, 3.1f};
std::list<float> l1(5, 1.1f);
std::list<float> l2(5);
std::list<float> l3(vec.begin(), vec.end());
std::list<float> l4(l1);
std::list<float> tmp(l1);
std::list<float> l5(std::move(tmp));
std::list<float> l6{11.1f, 12.1, 13.1f};

print_func(l1);
print_func(l2);
print_func(l3);
print_func(l4);
print_func(l5);
print_func(l6);

输出结果:

bash 复制代码
1.1 1.1 1.1 1.1 1.1 
0 0 0 0 0 
1.1 2.1 3.1 
1.1 1.1 1.1 1.1 1.1 
1.1 1.1 1.1 1.1 1.1 
11.1 12.1 13.1 

析构函数

list析构时,会按照正向顺序依次删除元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(int i)
        : Index(i)
    {
    }

    ~MyStruct()
    {
        std::cout << "destruct, Index = " << Index << std::endl;
    }

    int Index = 0;
};

std::list<MyStruct> l;
l.emplace_front(1);
l.emplace_front(3);
l.emplace_front(5);

输出结果:

bash 复制代码
destruct, Index = 5
destruct, Index = 3
destruct, Index = 1

赋值函数

可以用元素列表或者另一个list赋值给forward_list。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<float> tmp = {1.1f, 2.1f, 3.1f};
std::list<float> l1;
std::list<float> l2;

l1 = tmp;
l2 = {2.1f, 2.2f, 2.3f, 2.4f};
print_func(l1);
print_func(l2);

输出结果:

bash 复制代码
1.1 2.1 3.1 
2.1 2.2 2.3 2.4 

assign

将值赋值给forward_list,可以是元素、元素列表或者迭代器。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec(10, 1.2f);
std::list<float> l;

l.assign(5, 1.2);
print_func(l);
l.assign(vec.begin(), vec.end());
print_func(l);
l.assign({1.1f, 2.1f, 3.1f});
print_func(l);

输出结果:

bash 复制代码
1.2 1.2 1.2 1.2 1.2 
1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 1.2 
1.1 2.1 3.1 

元素访问

front

返回首个元素的引用。示例代码:

cpp 复制代码
std::list<float> l = {1.f, 2.f, 3.f};
l.front() = 4.1f;
std::cout << "l front is: " << l.front() << std::endl;

输出结果:

bash 复制代码
l front is: 4.1

back

返回最后一个元素的引用。示例代码:

cpp 复制代码
std::list<float> l = {1.f, 2.f, 3.f};
l.back() = 24.1f;
std::cout << "l back is: " << l.back() << std::endl;

输出结果:

bash 复制代码
l back is: 24.1

迭代器

接口begin、cbegin指向list起始的迭代器,end、cend指向末尾的迭代器。rbegin、crbegin指向起始的逆向迭代器,rend、crend指向末尾的逆向迭代器。代码示例:

cpp 复制代码
std::list<float> l = {1.1f, 2.1f, 3.1f};
for (auto iter = l.rbegin(); iter != l.rend(); ++iter)
{
    *iter += 27.f;
}

for (auto iter = l.crbegin(); iter != l.crend(); ++iter)
{
    std::cout << "num is: " << *iter << std::endl;
}

输出结果:

bash 复制代码
num is: 30.1
num is: 29.1
num is: 28.1

容量

empty

检查list是否为空。示例代码:

cpp 复制代码
std::list<float> l1 = {1.1f, 2.1f, 3.1f};
std::list<float> l2;
std::cout << std::boolalpha;
std::cout << "l1 empty: " << l1.empty() << std::endl;
std::cout << "l2 empty: " << l2.empty() << std::endl;

输出结果:

bash 复制代码
l1 empty: false
l2 empty: true

size

获取list元素的个数。代码示例:

cpp 复制代码
std::list<float> l1 = {1.1f, 2.1f, 3.1f};
std::list<float> l2;
std::cout << "l1 size = " << l1.size() << std::endl;
std::cout << "l2 size = " << l2.size() << std::endl;

输出结果:

bash 复制代码
l1 size = 3
l2 size = 0

max_size

返回可以容纳的最大元素个数。代码示例:

cpp 复制代码
struct MyStruct
{
    double num1;
    double num2;
    double num3;
    double num4;
};

std::list<float> l1;
std::list<double> l2;
std::list<MyStruct> l3;
std::cout << "l1 max size = " << l1.max_size() << std::endl;
std::cout << "l2 max size = " << l2.max_size() << std::endl;
std::cout << "l3 max size = " << l3.max_size() << std::endl;

输出结果:

bash 复制代码
l1 max size = 768614336404564650
l2 max size = 768614336404564650
l3 max size = 384307168202282325

修改器

clear

清除所有的元素。代码示例:

cpp 复制代码
std::list<float> l(3, 1.f);
std::cout << std::boolalpha;
std::cout << "l empty: " << l.empty() << std::endl;
l.clear();
std::cout << "l empty: " << l.empty() << std::endl;

输出结果:

bash 复制代码
l empty: false
l empty: true

insert

在指定的位置插入元素。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::vector<float> vec{40.1f, 40.2f};

std::list<float> l = {1.1f, 1.2f, 1.3f};
print_func(l);
l.insert(l.begin(), 15.7f);
print_func(l);
l.insert(std::next(l.begin(), 2), 3, 27.9f);
print_func(l);
l.insert(std::next(l.begin(), 1), vec.begin(), vec.end());
print_func(l);
l.insert(std::next(l.begin(), 1), {70.5f, 75.5f, 71.5f});
print_func(l);

输出结果:

bash 复制代码
1.1 1.2 1.3 
15.7 1.1 1.2 1.3 
15.7 1.1 27.9 27.9 27.9 1.2 1.3 
15.7 40.1 40.2 1.1 27.9 27.9 27.9 1.2 1.3 
15.7 70.5 75.5 71.5 40.1 40.2 1.1 27.9 27.9 27.9 1.2 1.3 

emplace

在指定位置一个元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

std::list<MyStruct> f;
f.emplace(f.begin(), 5.5f, 20);

输出结果:

cpp 复制代码
construct 5.5 20

erase

删除指定位置的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<float> l = {1.1f, 1.2f, 1.3f, 1.5f, 1.6f, 1.7f, 1.8f};
print_func(l);
l.erase(std::next(l.begin(), 1));
print_func(l);
l.erase(std::next(l.begin(), 1), std::next(l.begin(), 5));
print_func(l);

输出结果:

bash 复制代码
1.1 1.2 1.3 1.5 1.6 1.7 1.8 
1.1 1.3 1.5 1.6 1.7 1.8 
1.1 1.8 

push_back

将元素添加到末尾。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<float> l = {1.1f, 1.2f};
l.push_back(1.3f);
l.push_back(1.4f);
print_func(l);

输出结果:

bash 复制代码
1.1 1.2 1.3 1.4 

emplace_back

在列表末尾构造一个元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

std::list<MyStruct> l;
l.emplace_back(1.5f, 17);
l.emplace_back(2.3f, 4);

输出结果:

bash 复制代码
construct 1.5 17
construct 2.3 4

pop_back

移除末尾的元素。代码示例:

cpp 复制代码
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l back is: " << l.back() << std::endl;
l.pop_back();
std::cout << "l back is: " << l.back() << std::endl;

输出结果:

bash 复制代码
l back is: 1.3
l back is: 1.2

push_front

将元素添加到起始位置。代码示例:

cpp 复制代码
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l front is: " << l.front() << std::endl;
l.push_front(17.7f);
std::cout << "l front is: " << l.front() << std::endl;

输出结果:

bash 复制代码
l front is: 1.1
l front is: 17.7

emplace_front

在列表起始位置构造一个元素。代码示例:

cpp 复制代码
struct MyStruct
{
    MyStruct(float num1, int num2)
    {
        std::cout << "construct " << num1 << " " << num2 << std::endl;
    }
};

std::list<MyStruct> l;
l.emplace_front(2.7f, 17);
l.emplace_front(15.1f, 13);

输出结果:

bash 复制代码
construct 2.7 17
construct 15.1 13

pop_front

移除列表的首个元素。代码示例:

cpp 复制代码
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l front is: " << l.front() << std::endl;
l.pop_front();
std::cout << "l front is: " << l.front() << std::endl;

输出结果:

bash 复制代码
l front is: 1.1
l front is: 1.2

resize

重新设置元素的个数。代码示例:

cpp 复制代码
std::list<float> l = {1.1f, 1.2f, 1.3f};
std::cout << "l size is: " << l.size() << std::endl;
l.resize(2);
std::cout << "l size is: " << l.size() << std::endl;
l.resize(20);
std::cout << "l size is: " << l.size() << std::endl;

输出结果:

bash 复制代码
l size is: 3
l size is: 2
l size is: 20

swap

交换两个列表的元素内容。代码示例:

cpp 复制代码
std::list<float> l1 = {1.1f, 1.2f, 1.3f};
std::list<float> l2 = {2.1f, 2.2f};
l1.swap(l2);
std::cout << "l1 size = " << l1.size() << std::endl;
std::cout << "l2 size = " << l2.size() << std::endl;

输出结果:

bash 复制代码
l1 size = 2
l2 size = 3

操作

sort

对元素进行排序。代码示例:

cpp 复制代码
auto print_func = [](const std::list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<int> l = {7, 17, 5, 47, 25};
print_func(l);

l.sort();
print_func(l);

l.sort(
    [](int a, int b)
    {
        return a > b;
    });
print_func(l);

输出结果:

bash 复制代码
7 17 5 47 25 
5 7 17 25 47 
47 25 17 7 5 

merge

合并两个有序的列表。代码示例:

cpp 复制代码
auto print_func = [](const std::list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

{
    std::list<int> l1 = {1, 5, 7, 19};
    std::list<int> l2 = {2, 3, 14, 15};
    l1.merge(l2);
    print_func(l1);
}

{
    std::list<int> l1 = {1, 5, 7, 19};
    std::list<int> l2 = {2, 3, 14, 15};
    l1.merge(l2,
             [](int a, int b)
             {
                 return a > b;
             });
    print_func(l1);
}

输出结果:

bash 复制代码
1 2 3 5 7 14 15 19 
2 3 14 15 1 5 7 19 

splice

将另一个列表中的一些元素移动到this列表指定的位置。代码示例:

cpp 复制代码
auto print_func = [](std::string tag, const std::list<float>& list)
{
    std::cout << tag;
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

{
    std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
    l1.splice(l1.begin(), l2);
    print_func("l1 = ", l1);
    print_func("l2 = ", l2);
}

{
    std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
    l1.splice(std::next(l1.begin(), 2), l2, std::next(l2.begin(), 1));
    print_func("l1 = ", l1);
    print_func("l2 = ", l2);
}

{
    std::list<float> l1 = {1.5f, 5.5f, 7.5f, 19.5f};
    std::list<float> l2 = {2.4f, 3.4f, 14.4f, 15.4f};
    l1.splice(l1.begin(), l2, l2.begin(), std::next(l2.begin(), 2));
    print_func("l1 = ", l1);
    print_func("l2 = ", l2);
}

输出结果:

bash 复制代码
l1 = 2.4 3.4 14.4 15.4 1.5 5.5 7.5 19.5 
l2 = 
l1 = 1.5 5.5 3.4 7.5 19.5 
l2 = 2.4 14.4 15.4 
l1 = 2.4 3.4 1.5 5.5 7.5 19.5 
l2 = 14.4 15.4 

remove、remove_if

remove移除等于指定值的元素。remove_if移除满足指定要求的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<int> l = {5, 9, 17, 27, 15, 5, 5};
print_func(l);

l.remove(5);
print_func(l);

l.remove_if(
    [](int n)
    {
        return n > 15;
    });
print_func(l);

输出结果:

bash 复制代码
5 9 17 27 15 5 5 
9 17 27 15 
9 15 

reverse

反转元素的顺序。代码示例:

cpp 复制代码
auto print_func = [](const std::list<float>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<float> l = {1.1f, 3.1f, 19.1f, 7.1f};
print_func(l);
l.reverse();
print_func(l);

输出结果:

bash 复制代码
1.1 3.1 19.1 7.1 
7.1 19.1 3.1 1.1 

unique

删除连续的重复元素。代码示例:

cpp 复制代码
auto print_func = [](const std::list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<int> l = {1, 3, 3, 17, 7, 3, 17, 17, 19, 1, 3, 1};
print_func(l);
l.unique();
print_func(l);

输出结果:

bash 复制代码
1 3 3 17 7 3 17 17 19 1 3 1 
1 3 17 7 3 17 19 1 3 1 

非成员函数

比较运算符

operator==,!=,<,<=,>,>=用于比较两个forward_list。代码示例:

cpp 复制代码
std::list<int> l1 = {1, 2, 3, 4};
std::list<int> l2 = {1, 5};
std::cout << std::boolalpha;
std::cout << "l1 == l2: " << (l1 == l2) << std::endl;
std::cout << "l1 != l2: " << (l1 != l2) << std::endl;
std::cout << "l1 <  l2: " << (l1 < l2) << std::endl;
std::cout << "l1 <= l2: " << (l1 <= l2) << std::endl;
std::cout << "l1 >  l2: " << (l1 > l2) << std::endl;
std::cout << "l1 >= l2: " << (l1 >= l2) << std::endl;

输出结果:

bash 复制代码
l1 == l2: false
l1 != l2: true
l1 <  l2: true
l1 <= l2: true
l1 >  l2: false
l1 >= l2: false

swap

交换两个列表的元素内容。示例代码:

cpp 复制代码
std::list<float> l1 = {1.5f, 2.5f};
std::list<float> l2 = {17.1f, 15.1f, 27.1f};
std::swap(l1, l2);
std::cout << "l1 front is: " << l1.front() << std::endl;
std::cout << "l2 front is: " << l2.front() << std::endl;

输出结果:

bash 复制代码
l1 front is: 17.1
l2 front is: 1.5

erase、erase_if

erase删除等于指定值的元素,erase_if删除满足条件的元素。代码示例:

cpp 复制代码
auto print_func = [](const std::list<int>& list)
{
    for (auto i : list)
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;
};

std::list<int> l = {5, 7, 17, 29, 7, 7, 35};
print_func(l);

std::erase(l, 7);
print_func(l);

std::erase_if(l,
              [](int a)
              {
                  return a > 17;
              });
print_func(l);

输出结果:

bash 复制代码
5 7 17 29 7 7 35 
5 17 29 35 
5 17 
相关推荐
Fairy_sevenseven8 分钟前
【二十八】【QT开发应用】模拟WPS Tab
开发语言·qt·wps
_GR15 分钟前
每日OJ题_牛客_牛牛冲钻五_模拟_C++_Java
java·数据结构·c++·算法·动态规划
蜡笔小新星16 分钟前
Python Kivy库学习路线
开发语言·网络·经验分享·python·学习
凯子坚持 c16 分钟前
C语言复习概要(三)
c语言·开发语言
无限大.28 分钟前
c语言200例 067
java·c语言·开发语言
余炜yw29 分钟前
【Java序列化器】Java 中常用序列化器的探索与实践
java·开发语言
篝火悟者31 分钟前
问题-python-运行报错-SyntaxError: Non-UTF-8 code starting with ‘\xd5‘ in file 汉字编码问题
开发语言·python
Death20033 分钟前
Qt 中的 QListWidget、QTreeWidget 和 QTableWidget:简化的数据展示控件
c语言·开发语言·c++·qt·c#
六点半88834 分钟前
【C++】速通涉及 “vector” 的经典OJ编程题
开发语言·c++·算法·青少年编程·推荐算法
惜.己34 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5