C/C++ — STL中List用法

List 简述

std::list C++ 容器模版,T类型的双向链表。有序、可以在任意位置插入或删除。无法通过位置来访问元素,必须逐个遍历,可以通过开始元素或者最后一个元素遍历。

List 的使用

生成一个空的list容器:

std::list <std::string>  names;

初始化一个带有指定元素的列表:

std::list<std::string> names {20}; // A list of 20 empty strings

生成包含给定数量的相同元素列表:

std::list<double> values(50, 3.14159265);

50 个 double 型值的列表,并且每一个值都等于 3.14159265, 注意小括号与大括号的区别。

list 具有拷贝构造函数,因此可以直接生成一个现有list的副本:

std::list<double> save_values {values}; // Duplicate of values

可以用另一个序列的开始和结束迭代器所指定的一段元素,来构造 list 容器的初始化列表:

std::list<double> samples {++cbegin(values), --cend(values)};

增加和插入元素

list可以使用 push_front() 在它的头部添加一个元素。push_back() 可以在 list 容器的末尾添加一个元素:

std::list<std::string> names { "Jane", "Jim", "Jules", "Janet"};
names.push_front("Ian"); // Add string ("Ian") to the front of the list
names.push_back("Kitty"); // Append string ("Kitty") to the end of the list

这两个函数都有右值引用参数的版本,这种版本的函数会移动参数而不是从参数复制新的元素。它们显然要比其他使用左值引用参数的版本高效。然而,成员函数 emplace_front() 和 emplace_back() 可以做得更好:

names.emplace_front("Ian");//Create string ("Ian") in place at the front of the list
names.emplace_back("Kitty");// Create string ("Kitty") in place at the end of the list
  1. 可以在迭代器指定的位置插入一个新的元素:
std::list<int> data(10, 55); // List of 10 elements with value 55
data.insert(++begin(data), 66); // Insert 66 as the second element
  1. 可以在给定位置插入几个相同元素的副本:
auto iter = begin(data);
std::advance(iter, 9); // Increase iter by 9
data.insert(iter, 3, 88);// Insert 3 copies of 88 starting at the 10th

List删除元素

list 容器的成员函数 remove() 则移除和参数匹配的元素:

std::list<int> numbers { 2, 5, 2, 3, 6, 7, 8, 2, 9};
numbers.remove(2); // List is now 5 3 6 7 8 9

成员函数 remove_if() 期望传入一个一元断言作为参数。一元断言接受一个和元素同类型的参数或引用,返回一个布尔值。断言返回 true 的所有元素都会被移除:

numbers.remove_if([](int n){return n%2 == 0;});// Remove even numbers. Result 5 3 7 9

成员函数 unique() 非常有意思,它可以移除连续的重复元素,只留下其中的第一个。例如:

std::list<std::string> words { "one", "two", "two", "two","three", "four", "four"};
words.unique () ; // Now contains "one" "two" "three" "four"

这个版本的 unique() 函数使用 == 运算符比较连续元素。可以在对元素进行排序后,再使用 unique(),这样可以保证移除序列中全部的重复元素。

List排序及合并

sort(): sort() 有两个版本:无参 sort() 函数将所有元素升序排列。第二个版本的 sort() 接受一个函数对象或 lambda 表达式作为参数,这两种参数都定义一个断言用来比较两个元素。

// Order strings by length when the initial letters are the same
class my_greater
{
    public:
    bool operator () (const std::strings s1, const std::strings s2)
    {
        if (s1[0] == s2 [0])
            return si.length() > s2.length();
        else
            return s1 > s2;
    }
};
names.sort(my_greater()); // Sort using my_greater

list 的成员函数 merge() 以另一个具有相同类型元素的 list 容器作为参数。两个容器中的元素都必须是升序。参数 list 容器中的元素会被合并到当前的 list 容器中。例如:

std::list<int> my_values {2, 4, 6, 14};
std::list<int> your_values{ -2, 1, 7, 10};
my_values.merge (your_values);//my_values contains: -2 1 2 4 6 7 10 14
your_values.empty(); // Returns true

在另一个版本的 merge() 函数中,可以提供一个比较函数作为该函数的第二个参数,用来在合并过程中比较元素。例如:

std::list<std::string> my_words { "three","six", "eight"};
std::list<std::string> your_words { "seven", "four", "nine"};
auto comp_str = [](const std::strings s1, const std::strings s2){ return s1[0]<s2[0];};
my_words.sort (comp_str); //"eight" "six" "three"
your_words.sort (comp_str) ;  //"four" "nine" "seven"
my_words.merge (your_words, comp_str) ; // "eight" "four" "nine" "six" "seven" "three"

ist 容器的成员函数 splice() 有几个重载版本。这个函数将参数 list 容器中的元素移动到当前容器中指定位置的前面。可以移动单个元素、一段元素或源容器的全部元素。下面是一个剪切单个元素的示例:

std::list<std::string> my_words {"three", "six", "eight"};
std::list<std::string> your_words {"seven", "four", "nine"};
my_words.splice(++std::begin(my_words), your_words, ++std::begin(your_words));

splice() 的第一个参数是指向目的容器的迭代器。第二个参数是元素的来源。第三个参数是一个指向源list容器中被粘接元素的迭代器,它会被插入到第一个参数所指向位置之前。

常用方法

1、begin()和end()

通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator,可以调用list容器的end()函数来得到list末端下一位置。

2、empty()

判断list是否为空,PS:误用.size()来判断是否为空,否则效率浪费。

3、resize()

调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除。如果n比list原来的长度长,那么默认超出的部分元素置为0。也可以用resize(n, m)的方式将超出的部分赋值为m。

list<int>b{1, 2, 3, 4};
b.resize(2);
list中输出元素:1,2
list<int>b{1, 2, 3, 4};
b.resize(6);
list中输出元素:1,2,3,4,0,0
list<int>b{1, 2, 3, 4};
b.resize(6,9);
list中输出元素:1,2,3,4,9,9

4、 clear()

清空list中的所有元素

5、front()和back()

通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。注意:当list元素为空时,这时候调用front()和back()不会报错。因此在编写程序时,最好先调用empty()函数判断list是否为空,再调用front()和back()函数。

6、 pop_back()和pop_front()

使用pop_back()可以删掉尾部第一个元素,pop_front()可以删掉头部第一个元素。注意:list必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉

7、assign()

(1)、a.assign(n, val):将a中的所有元素替换成n个val元素

list<int>b{1,2,3,4,5};
b.assign(5,10);

b中的元素变为10, 10, 10, 10, 10

(2)、a.assign(b.begin(), b.end())

list<int>a{6,7,8,9};
list<int>b{1,2,3,4,5};
b.assign(a.begin(),a.end());

b中的元素变为6,7,8,9

8、swap()

交换两个链表。a.swap(b)和swap(a, b),都可以完成a链表和b链表的交换。

9、reverse()

可以实现list的逆置

10、merge()

a.merge(b) 调用结束后b变为空,a中元素包含原来a和b的元素。

list<int>a{6,7,8,9};
list<int>b{2, 1, 3, 6, 5};
a.merge(b,greater<int>());

// Demo 2
list<int>a{6,7,8,9};
list<int>b{2, 1, 3, 6, 5};
a.merge(b);
11、insert()

在指定位置插入一个或多个元素

a.insert(a.begin(),100);  //在a的开始位置(即头部)插入100
a.insert(a.begin(),2, 100);   //在a的开始位置插入2个100
a.insert(a.begin(),b.begin(), b.end());//在a的开始位置插入b从开始到结束的所有位置的元素
12、remove()

从list中删除元素

list<int>a{6,7,8,9,7,10};
a.remove(7);
// 删除了a中所有值为7的元素,此时a中元素为6,8,9,10
13、remove_if()

括号中可以传入:回调函数、创建用于比较的类,传入类名及初始化参数。

  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值