【C++】list的使用(下)

简介: `C++` 中 `std::list` 的 `merge()`、`sort()` 和 `reverse()` 操作:- `merge(x)` 和 `merge(x, comp)`: 合并两个已排序的`list`,将`x`的元素按顺序插入当前`list`,`x`清空。比较可自定义。- `sort()` 和 `sort(comp)`: 对`list`元素排序,保持等价元素相对顺序。内置排序基于稳定排序算法,速度较慢。-reverse(): 反转`list`中元素的顺序。这些操作不涉及元素构造/销毁,直接移动元素。注意,`sort()`不适合`std::list`,因链表结构不利于快速排序

==merge==

在这里插入图片描述
(1)

void merge (list& x);

(2)

template <class Compare>
  void merge (list& x, Compare comp);

合并有序链表

该函数通过将x中的所有元素按其各自的有序位置转移到容器中,来将x合并到列表中(两个容器都应当已经是有序的)。

这实际上移除了x中的所有元素(x变为空),并将它们插入到容器中的有序位置(容器的大小会增加转移的元素数量)。这个操作不需要构造或销毁任何元素:它们是被转移的,无论x是左值还是右值,或者value_type是否支持移动构造。

带有两个参数的模板版本(2)具有相同的行为,但是它们接受一个特定的谓词(comp)来执行元素之间的比较操作。这个比较应当产生元素的一个严格弱序(即,一个一致的传递性比较,不考虑其自反性)。

这个函数要求列表容器在调用之前已经根据值(或根据comp)对其元素进行了排序。对于无序列表的替代方案,请参见list::splice

假设存在这样的排序,x中的每个元素都根据其值插入到由<运算符或comp定义的严格弱序所对应的位置。结果中,等价元素的顺序是稳定的(即,等价元素保持它们在调用之前的相对顺序,并且现有元素优先于从x中插入的等价元素)。

如果&x == this(即,尝试将一个列表合并到它自己中),则该函数什么也不做。

代码案例:

// list::merge
#include <iostream>
#include <list>

// compare only integral part:
bool mycomparison(double first, double second)
{
   
   
    return (int(first) < int(second));
}

int main()
{
   
   
    std::list<double> first, second;

    first.push_back(3.1);
    first.push_back(2.2);
    first.push_back(2.9);

    second.push_back(3.7);
    second.push_back(7.1);
    second.push_back(1.4);

    first.sort();
    second.sort();

    first.merge(second);

    // (second is now empty)

    second.push_back(2.1);

    first.merge(second, mycomparison);

    std::cout << "first contains:";
    for (std::list<double>::iterator it = first.begin(); it != first.end(); ++it)
        std::cout << ' ' << *it;
    std::cout << '\n';

    return 0;
}

在这里插入图片描述

==sort==

在这里插入图片描述
(1)

void sort();

(2)

template <class Compare>
  void sort (Compare comp);

排序list对象中的元素

该函数会对列表中的元素进行排序,改变它们在容器中的位置

排序操作通过应用一个算法来完成,该算法使用 < 运算符(在版本 (1) 中)或 comp(在版本 (2) 中)来比较元素。这个比较应当产生元素的一个严格弱序(即,一个一致的传递性比较,不考虑其自反性)。

排序后,等价元素的顺序是稳定的:即,等价元素保持它们在调用之前的相对顺序。

整个操作不涉及任何元素对象的构造、销毁或复制。元素在容器内部进行移动。

#include<iostream>
#include<list>

class great
{
   
   
public:
    bool operator()(int x, int y)
    {
   
   
        return x > y;
    }
};

int main()
{
   
   
    std::list<int> lt({
   
    9,3,4,7,1 });
    for (auto e : lt)std::cout << e << " ";
    std::cout << std::endl;

    lt.sort();
    for (auto e : lt)std::cout << e << " ";
    std::cout << std::endl;

    lt.sort(great());
    for (auto e : lt)std::cout << e << " ";
    std::cout << std::endl;

    return 0;
}

在这里插入图片描述

该排序的底层是堆排序,速度会比快排慢上2~3倍。同时algorithm中的sort不支持排序list对象的元素,因为链表由于其自生结构特点难以实现快排的逻辑。

==reverse==

在这里插入图片描述

void reverse();

反转list对象中的元素

代码案例:

#include<iostream>
#include<list>

int main()
{
   
   
    std::list<int> lt({
   
    9,3,4,7,1 });
    for (auto e : lt)std::cout << e << " ";
    std::cout << std::endl;

    lt.reverse();
    for (auto e : lt)std::cout << e << " ";
    std::cout << std::endl;

    return 0;
}

在这里插入图片描述

结语

本篇文章所讲到的list内容出自于同一个模块,由于其排序和合并的方式涉及到了仿函数的传递,所以内容和篇幅稍微会大一些。相信学完本篇内容之后,能对list的使用和C++有更充分的了解。
博主后续还会产出更多有趣的的内容,感谢大家的支持。♥

相关文章
|
2天前
|
存储 编译器 C语言
【C++】list模拟实现
本文档介绍了C++ STL中`list`容器的模拟实现,包括`ListNode`节点类、迭代器类和`list`类的详细设计。`ListNode`模板类存储数据并维护前后指针;`ListIterator`是一个复杂的模板类,提供解引用、自增/自减以及比较操作。`list`类包含了链表的各种操作,如插入、删除、访问元素等,并使用迭代器作为访问接口。实现中,迭代器不再是简单的指针,而是拥有完整功能的对象。此外,文档还提到了迭代器的实现对C++语法的特殊处理,使得`it-&gt;_val`的写法成为可能。文章通过分步骤展示`list`的各个组件的实现,帮助读者深入理解STL容器的内部工作原理。
|
2天前
|
C++ 容器
【C++】list的使用(下)
这篇博客探讨了C++ STL中`list`容器的几个关键操作,包括`splice()`、`remove()`、`remove_if()`和`unique()`。`splice()`允许高效地合并或移动`list`中的元素,无需构造或销毁。`remove()`根据值删除元素,而`remove_if()`则基于谓词移除元素。`unique()`则去除连续重复的元素,可选地使用自定义比较函数。每个操作都附带了代码示例以说明其用法。
|
2天前
|
编译器 C++ 容器
【C++】list的使用(上)
迭代器在STL中统一了访问接口,如`list`的`begin()`和`end()`。示例展示了如何使用正向和反向迭代器遍历`list`。注意`list`的迭代器不支持加减操作,只能用`++`和`--`。容器的`empty()`和`size()`用于检查状态和获取元素数。`front()`和`back()`访问首尾元素,`assign()`重载函数用于替换内容,`push_*/pop_*`管理两端元素,`insert()`插入元素,`erase()`删除元素,`resize()`调整大小,`clear()`清空容器。这些接口与`vector`和`string`类似,方便使用。
|
3天前
|
存储 C++
C++的list-map链表与映射表
```markdown C++ 中的`list`和`map`提供链表和映射表功能。`list`是双向链表,支持头尾插入删除(`push_front/push_back/pop_front/pop_back`),迭代器遍历及任意位置插入删除。`map`是键值对集合,自动按键排序,支持直接通过键来添加、修改和删除元素。两者均能使用范围for循环遍历,`map`的`count`函数用于统计键值出现次数。 ```
13 1
|
11天前
|
编译器 C++ 容器
【C++/STL】:list容器的深度剖析及模拟实现
【C++/STL】:list容器的深度剖析及模拟实现
13 2
|
14天前
|
存储 算法 C++
C++一分钟之-容器概览:vector, list, deque
【6月更文挑战第21天】STL中的`vector`是动态数组,适合随机访问,但插入删除非末尾元素较慢;`list`是双向链表,插入删除快但随机访问效率低;`deque`结合两者优点,支持快速双端操作。选择容器要考虑操作频率、内存占用和性能需求。注意预分配容量以减少`vector`的内存重分配,使用迭代器而非索引操作`list`,并利用`deque`的两端优势。理解容器内部机制和应用场景是优化C++程序的关键。
25 5
|
10天前
|
编译器 C语言 C++
C++ STL中list迭代器的实现
C++ STL中list迭代器的实现
C++ STL中list迭代器的实现
|
11天前
|
存储 C++ 容器
【C++/STL】:list容器的基本使用
【C++/STL】:list容器的基本使用
11 1
|
2天前
|
存储 编译器 C语言
【C++】list的使用(上)
**C++ STL的list是一个基于双向循环链表的容器,支持常数时间内插入和删除,但不支持随机访问。默认构造函数、填充构造、迭代器范围构造和拷贝构造提供多种初始化方式。析构函数自动释放内存,赋值运算符重载用于内容替换。示例代码展示了构造和赋值操作。**
|
2天前
|
存储 算法 程序员
C++基础知识(八:STL标准库(Vectors和list))
C++ STL (Standard Template Library标准模板库) 是通用类模板和算法的集合,它提供给程序员一些标准的数据结构的实现如 queues(队列), lists(链表), 和 stacks(栈)等. STL容器的提供是为了让开发者可以更高效率的去开发,同时我们应该也需要知道他们的底层实现,这样在出现错误的时候我们才知道一些原因,才可以更好的去解决问题。