std::list C++ 容器模版,T类型的双向链表。有序、可以在任意位置插入或删除。无法通过位置来访问元素,必须逐个遍历,可以通过开始元素或者最后一个元素遍历。
生成一个空的list容器:
std::list names;
初始化一个带有指定元素的列表:
std::list names {20}; // A list of 20 empty strings
生成包含给定数量的相同元素列表:
std::list values(50, 3.14159265);
50 个 double 型值的列表,并且每一个值都等于 3.14159265, 注意小括号与大括号的区别。
list 具有拷贝构造函数,因此可以直接生成一个现有list的副本:
std::list save_values {values}; // Duplicate of values
可以用另一个序列的开始和结束迭代器所指定的一段元素,来构造 list 容器的初始化列表:
std::list samples {++cbegin(values), --cend(values)};
list可以使用 push_front() 在它的头部添加一个元素。push_back() 可以在 list 容器的末尾添加一个元素:
std::list 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
std::list data(10, 55); // List of 10 elements with value 55
data.insert(++begin(data), 66); // Insert 66 as the second element
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 容器的成员函数 remove() 则移除和参数匹配的元素:
std::list 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 words { "one", "two", "two", "two","three", "four", "four"};
words.unique () ; // Now contains "one" "two" "three" "four"
这个版本的 unique() 函数使用 == 运算符比较连续元素。可以在对元素进行排序后,再使用 unique(),这样可以保证移除序列中全部的重复元素。
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 my_values {2, 4, 6, 14};
std::list 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 my_words { "three","six", "eight"};
std::list your_words { "seven", "four", "nine"};
auto comp_str = [](const std::strings s1, const std::strings s2){ return s1[0]
ist 容器的成员函数 splice() 有几个重载版本。这个函数将参数 list 容器中的元素移动到当前容器中指定位置的前面。可以移动单个元素、一段元素或源容器的全部元素。下面是一个剪切单个元素的示例:
std::list my_words {"three", "six", "eight"};
std::list your_words {"seven", "four", "nine"};
my_words.splice(++std::begin(my_words), your_words, ++std::begin(your_words));
splice() 的第一个参数是指向目的容器的迭代器。第二个参数是元素的来源。第三个参数是一个指向源list容器中被粘接元素的迭代器,它会被插入到第一个参数所指向位置之前。
通过调用list容器的成员函数begin()得到一个指向容器起始位置的iterator,可以调用list容器的end()函数来得到list末端下一位置。
判断list是否为空,PS:误用.size()来判断是否为空,否则效率浪费。
调用resize(n)将list的长度改为只容纳n个元素,超出的元素将被删除。如果n比list原来的长度长,那么默认超出的部分元素置为0。也可以用resize(n, m)的方式将超出的部分赋值为m。
listb{1, 2, 3, 4};
b.resize(2);
list中输出元素:1,2
listb{1, 2, 3, 4};
b.resize(6);
list中输出元素:1,2,3,4,0,0
listb{1, 2, 3, 4};
b.resize(6,9);
list中输出元素:1,2,3,4,9,9
清空list中的所有元素
通过front()可以获得list容器中的头部元素,通过back()可以获得list容器的最后一个元素。注意:当list元素为空时,这时候调用front()和back()不会报错。因此在编写程序时,最好先调用empty()函数判断list是否为空,再调用front()和back()函数。
使用pop_back()可以删掉尾部第一个元素,pop_front()可以删掉头部第一个元素。注意:list必须不为空,如果当list为空的时候调用pop_back()和pop_front()会使程序崩掉。
(1)、a.assign(n, val):将a中的所有元素替换成n个val元素
listb{1,2,3,4,5};
b.assign(5,10);
b中的元素变为10, 10, 10, 10, 10
(2)、a.assign(b.begin(), b.end())
lista{6,7,8,9};
listb{1,2,3,4,5};
b.assign(a.begin(),a.end());
b中的元素变为6,7,8,9
交换两个链表。a.swap(b)和swap(a, b),都可以完成a链表和b链表的交换。
可以实现list的逆置
a.merge(b) 调用结束后b变为空,a中元素包含原来a和b的元素。
lista{6,7,8,9};
listb{2, 1, 3, 6, 5};
a.merge(b,greater());
// Demo 2
lista{6,7,8,9};
listb{2, 1, 3, 6, 5};
a.merge(b);
在指定位置插入一个或多个元素
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从开始到结束的所有位置的元素
从list中删除元素
lista{6,7,8,9,7,10};
a.remove(7);
// 删除了a中所有值为7的元素,此时a中元素为6,8,9,10
括号中可以传入:回调函数、创建用于比较的类,传入类名及初始化参数。