c++标准模板(STL)(std::list)(十二)

定义于头文件 <list>

template<  class T,  class Allocator = std::allocator<T> > class list;    (1)    
namespace pmr { template <class T>
 
using list = std::list<T, std::pmr::polymorphic_allocator<T>>;}  (2)    (C++17 起)

std::list 是支持常数时间从容器任何位置插入和移除元素的容器。不支持快速随机访问。它通常实现为双向链表。与 std::forward_list 相比,此容器提供双向迭代但在空间上效率稍低。

在 list 内或在数个 list 间添加、移除和移动元素不会非法化迭代器或引用。迭代器仅在对应元素被删除时非法化。

std::list 满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 及可逆容器 (ReversibleContainer) 的要求。

删除连续的重复元素

std::list<T,Allocator>::unique

void unique();

(1)(C++20 前)

size_type unique();

(C++20 起)

template< class BinaryPredicate >
void unique( BinaryPredicate p );

(2)(C++20 前)

template< class BinaryPredicate >
size_type unique( BinaryPredicate p );

(C++20 起)

从容器移除所有相继的重复元素。只留下相等元素组中的第一个元素。第一版本用 operator== 比较元素,第二版本用二元谓词 p 比较元素

参数

p-若元素应被当做相等则返回 ​true 的二元谓词。

谓词函数的签名应等价于如下:

 bool pred(const Type1 &a, const Type2 &b);

虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 与 Type2 必须使得 list<T,Allocator>::const_iterator 类型的对象能在解引用后隐式转换到这两个类型。 ​

返回值

(无)

(C++20 前)

移除的元素数。

(C++20 起)

复杂度

与容器大小成线性

调用示例

#include <iostream>
#include <list>

int main()
{
    std::list<int> x = {1, 2, 2, 3, 3, 2, 1, 1, 2};

    std::cout << "contents before:";
    for (auto val : x)
    {
        std::cout << ' ' << val;
    }
    std::cout << '\n';

    x.unique();
    std::cout << "contents after unique():";
    for (auto val : x)
    {
        std::cout << ' ' << val;
    }
    std::cout << '\n';

    return 0;
}

输出

对元素进行排序

std::list<T,Allocator>::sort

void sort();

(1)

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

(2)

以升序排序元素。保持相等元素的顺序。第一版本用 operator< 比较元素,第二版本用给定的比较函数 comp

若抛出异常,则 *this 中元素顺序未指定。

参数

comp-比较函数对象(即满足比较 (Compare) 概念的对象),若第一参数小于(即序于)第二参数则返回 ​true 。

比较函数的签名应等价于如下:

 bool cmp(const Type1 &a, const Type2 &b);

虽然签名不必有 const & ,函数也不能修改传递给它的对象,而且必须接受(可为 const 的)类型 Type1Type2 的值,无关乎值类别(从而不允许 Type1 & ,亦不允许 Type1 ,除非 Type1 的移动等价于复制 (C++11 起))。
类型 Type1 与 Type2 必须使得 list<T,Allocator>::const_iterator 类型的对象能在解引用后隐式转换到这两个类型。 ​

返回值

(无)

复杂度

大约 N log N 次比较,其中 N 是表中的元素数。

注意

std::sort 要求随机访问迭代器且不能用于 list 。此函数与 std::sort 的区别在于,它不要求 list 的元素类型可交换,保留所有迭代器的值,并进行稳定排序。

 调用示例

#include <iostream>
#include <functional>
#include <list>

std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
    for (auto &i : list)
    {
        ostr << " " << i;
    }
    return ostr;
}

int main()
{
    std::list<int> list = { 8, 7, 5, 9, 0, 1, 3, 2, 6, 4 };

    std::cout << "before:     " << list << "\n";
    list.sort();
    std::cout << "ascending:  " << list << "\n";
    list.sort(std::greater<int>());
    std::cout << "descending: " << list << "\n";
}

输出

按照字典顺序比较 list 中的值

operator==,!=,<,<=,>,>=(std::list)
template< class T, class Alloc >

bool operator==( const std::list<T,Alloc>& lhs,

                 const std::list<T,Alloc>& rhs );
(1)
template< class T, class Alloc >

bool operator!=( const std::list<T,Alloc>& lhs,

                 const std::list<T,Alloc>& rhs );
(2)
template< class T, class Alloc >

bool operator<( const std::list<T,Alloc>& lhs,

                const std::list<T,Alloc>& rhs );
(3)
template< class T, class Alloc >

bool operator<=( const std::list<T,Alloc>& lhs,

                 const std::list<T,Alloc>& rhs );
(4)
template< class T, class Alloc >

bool operator>( const std::list<T,Alloc>& lhs,

                const std::list<T,Alloc>& rhs );
(5)
template< class T, class Alloc >

bool operator>=( const std::list<T,Alloc>& lhs,

                 const std::list<T,Alloc>& rhs );
(6)

 比较二个容器的内容。

1-2) 检查 lhsrhs 的内容是否相等,即它们是否拥有相同数量的元素且 lhs 中每个元素与 rhs 的同位置元素比较相等。

3-6) 按字典序比较 lhsrhs 的内容。由等价于 std::lexicographical_compare 的函数进行比较。

参数

lhs, rhs-要比较内容的容器
- 为使用重载 (1-2) , T 必须满足可相等比较 (EqualityComparable) 的要求。
- 为使用重载 (3-6) , T 必须满足可小于比较 (LessThanComparable) 的要求。顺序关系必须建立全序。

返回值

1) 若容器内容相等则为 true ,否则为 false

2) 若容器内容不相等则为 true ,否则为 false

3) 若 lhs 的内容按字典序小于 rhs 的内容则为 true ,否则为 false

4) 若 lhs 的内容按字典序小于等于 rhs 的内容则为 true ,否则为 false

5) 若 lhs 的内容按字典序大于 rhs 的内容则为 true ,否则为 false

6) 若 lhs 的内容按字典序大于等于 rhs 的内容则为 true ,否则为 false

复杂度

1-2) 若 lhsrhs 的大小不同则为常数,否则与容器大小成线性

3-6) 与容器大小成线性

调用示例

#include <iostream>
#include <list>

int main()
{
    std::list<int> list1 = { 1, 2, 3};
    std::list<int> list2 = { 1, 2, 3, 4};
    std::list<int> list3 = { 3, 2, 1};
    std::list<int> list4 = { 3 };
    std::list<int> list5;
    std::list<int> list6 = {1, 2, 3};

    std::cout << std::boolalpha << "list1 == list2  " << (list1 == list2) << std::endl;
    std::cout << std::boolalpha << "list1 != list3  " << (list1 != list3) << std::endl;
    std::cout << std::boolalpha << "list1 >  list4  " << (list1 >  list4) << std::endl;
    std::cout << std::boolalpha << "list1 >= list5  " << (list1 >= list5) << std::endl;
    std::cout << std::boolalpha << "list1 <  list6  " << (list1 <  list6) << std::endl;
    std::cout << std::boolalpha << "list2 <= list5  " << (list1 <= list5) << std::endl;
}

输出

特化 std::swap 算法

std::swap(std::list)
template< class T, class Alloc >
void swap( list<T,Alloc>& lhs,
           list<T,Alloc>& rhs );  (C++17 前) 

template< class T, class Alloc >
void swap( list<T,Alloc>& lhs,
           list<T,Alloc>& rhs ) noexcept(/* see below */);  (C++17 起) 

为 std::list 特化 std::swap 算法。交换 lhsrhs 的内容。调用 lhs.swap(rhs) 。

参数

lhs, rhs-要交换内容的容器

返回值

(无)

复杂度

常数。

异常

noexcept 规定:  

noexcept(noexcept(lhs.swap(rhs)))

(C++17 起)

调用示例 

#include <iostream>
#include <list>

std::ostream& operator<<(std::ostream& ostr, const std::list<int>& list)
{
    for (auto &i : list)
    {
        ostr << " " << i;
    }
    return ostr;
}

int main()
{
    std::list<int> list1 = { 1, 2, 3, 4, 5 };
    std::list<int> list2 = { 10, 20, 30, 40, 50 };

    std::cout << "swap before list1: " << list1 << "\n";
    std::cout << "swap before list2: " << list2 << "\n\n";

    std::swap(list1, list2);

    std::cout << "swap after list1: " << list1 << "\n";
    std::cout << "swap after list2: " << list2 << "\n";
}

输出

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值