列表(List)
list是序列容器,允许在序列中的任何位置进行插入和删除操作,并在两个方向上进行迭代。
list容器实现为双向链表;双向链表可以将它们包含的每个元素存储在不同且不相关的存储位置中。排序由内部保留,每个元素都有指向前面以及后面的元素的两个链接。
list与forward_list非常相似:主要区别在于forward_list对象是单向链表,因此只能向前迭代,以换取更小和更高效。
与其他基本标准序列容器(array,vector和deque)相比,list在插入元素,提取元素和以及迭代器在容器内的任何位置中移动元素时通常表现更好,因此在大量的算法中使用list,比如排序算法。
与其他序列容器相比,list和forward_lists的主要缺点是它们无法通过位置直接访问元素;例如,要访问列表中的第6个元素,必须从已知位置(如开头或结尾)迭代到该位置,这将在这些位置之间的距离中耗掉一些时间,还消耗一些额外的内存来保存与每个元素相关联的链接信息。
容器属性
(1) 序列
序列容器中的元素按严格的线性顺序排序。各个元素按其顺序访问它们的位置。
(2)双向链表
每个元素保存有关如何定位下一个元素和前一个元素的信息,允许在特定元素之前或之后(甚至整个范围)进行恒定时间插入和擦除操作,但不允许直接随机访问。
(3)分配器
容器使用allocator对象来动态处理其存储需求。
构造函数:
C++11中list的构造函数有如下:
(1)空容器构造函数(默认构造函数)
explicit list (const allocator_type& alloc = allocator_type());
构造一个没有元素的空list。
(2)填充构造函数
explicit list (size_type n);
list (size_type n, const value_type& val, const allocator_type& alloc = allocator_type());
构造一个包含n个元素的list。 每个元素都是val的副本(如果提供)。
(3)范围构造函数
template <class InputIterator>
list (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
构造一个list,其中包含与[first,last]范围一样多的元素,每个元素都以相同的顺序从该范围内的相应元素构造。
(4)拷贝构造函数(和使用allocator复制)
list (const list& x);
list (const list& x, const allocator_type& alloc);
构造一个list,其中包含x中每个元素的副本,顺序相同。
(5)移动构造函数(和分配器一起移动)
list (list&& x);
list (list&& x, const allocator_type& alloc);
构造一个获取x元素的list。
如果指定了alloc并且与x的allocator不同,则移动元素。否则,不构建任何元素(它们的所有权直接转移)。
(6)初始化列表构造函数
list (initializer_list<value_type> il, const allocator_type& alloc = allocator_type());
构造一个list,其中包含il中每个元素的副本,顺序相同。
// constructing lists
#include <iostream>
#include <list>
int main ()
{
using namespace std;
// constructors used in the same order as described above:
list<int> one; //Constructs an empty list, with no elements.
list<int> two(10, 100); //Constructs a list with 10 elements. Each element is 100.
list<int> three(two.begin(), two.end()); //Constructs a list with as many elements as the two.
list<int> four(three); //Constructs a list with a copy of each of the elements in three.
cout << "1. four are: ";
for(auto& x : four)
{
cout << " " << x;
}
cout << endl;
list<int> five(move(four)); //Constructs a list that acquires the elements of four.
cout << "2. four are: ";
for(auto& x : four)
{
cout << " " << x;
}
cout << endl;
cout << "2. five are: ";
for(auto& x : five)
{
cout << " " << x;
}
cout << endl;
return 0;
}
Iterator:
begin
将迭代器返回到开头(公共成员函数)
end
将迭代器返回到end(公共成员函数)
rbegin
返回反向迭代器以反向开始(公共成员函数)
rend
将反向迭代器返回到反向结束(公共成员函数)
cbegin
将const_iterator返回到开头(公共成员函数)
cend
将const_iterator返回到end(公共成员函数)
crbegin
返回const_reverse_iterator以反向开始(公共成员函数)
crend
将const_reverse_iterator返回到反向结束(公共成员函数)
// list::begin/end
// list::cbegin/cend
// list::rbegin/rend
// list::crbegin/crend
#include <iostream>
#include <list>
int main ()
{
using namespace std;
int myarray[] = {1, 2, 3, 4, 5};
list<int> mylist (myarray, myarray+5);
cout << "mylist contains:";
for (list<int>::iterator it=mylist.begin(); it != mylist.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
cout << "mylist contains:";
for (auto it = mylist.cbegin(); it != mylist.cend(); ++it)
{
cout << " " << *it;
}
cout << endl;
cout << "mylist backwards:";
for (list<int>::reverse_iterator rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
{
cout << " " << *rit;
}
cout << endl;
cout << "mylist backwards:";
for (auto rit = mylist.crbegin(); rit != mylist.crend(); ++rit)
{
cout << " " << *rit;
}
cout << endl;
return 0;
}
Capacity:
empty
测试容器是否为空(公共成员函数)
size
返回大小(公共成员函数)
max_size
返回最大大小(公共成员函数)
// list::empty
// list::size
// list::max_size
#include <iostream>
#include <list>
int main ()
{
using namespace std;
list<int> mylist1;
int sum = 0;
cout << "0. mylist1 size: " << mylist1.size() << endl;
for (int i=1;i<=10;++i)
{
mylist1.push_back(i);
}
cout << "1. mylist1 size: " << mylist1.size() << endl;
while (!mylist1.empty())
{
sum += mylist1.front();
mylist1.pop_front();
}
cout << "total: " << sum << endl;
unsigned int i;
list<int> mylist2;
cout << "2. mylist2 max_size: " << mylist2.max_size() << endl;
cout << "Enter number of elements: ";
cin >> i;
if (i<mylist2.max_size())
{
mylist2.resize(i);
}
else
{
cout << "That size exceeds the mylist1 limit." << endl;
}
cout << "2. mylist2 size: " << mylist2.size() << endl;
return 0;
}
Element access:
front
访问第一个元素(公共成员函数)
back
访问最后一个元素(公共成员函数)
// list::front
// list::back
#include <iostream>
#include <list>
int main ()
{
using namespace std;
list<int> mylist;
mylist.push_back(100);
mylist.push_back(90);
mylist.front() -= mylist.back();
cout << "mylist.front() is now " << mylist.front() << endl;
return 0;
}
Modifiers:
assign
将新内容分配给容器(公共成员函数)
emplace_front
在链表开头构造并插入元素(公共成员函数)
push_front
在链表开头插入元素(公共成员函数)
pop_front
删除第一个元素(公共成员函数)
emplace_back
在链表最后构造并插入元素(公共成员函数)
push_back
在链表最后添加元素(公共成员函数)
pop_back
删除最后一个元素(公共成员函数)
emplace
构造并插入元素(公共成员函数)
insert
插入元素(公共成员函数)
erase
擦除元素(公共成员函数)
swap
交换内容(公共成员函数)
resize
更改大小(公共成员函数)
clear
清除list内容(公共成员函数)
// list::assign
// list::push_front/pop_front
// list::push_back/pop_back
// list::emplace/emplace_front/emplace_back
// list::insert
// list::erase
// list::swap
// list::clear
// list::resize
#include <iostream>
#include <list>
int main ()
{
using namespace std;
list<int> one;
list<int> two;
list<int> three;
one.assign(5, 10);
two.assign(one.begin(), one.end());
int myarray[] = {1, 2, 3, 4, 5};
three.assign(myarray, myarray+5);
one.push_front(123);
one.push_back(789);
three.pop_front();
three.pop_back();
two.insert(two.end(), 456);
two.erase(two.begin());
one.swap(three);
list<int>::iterator it = one.begin();
it++;
one.emplace(it, 987);
two.emplace_front(987);
three.emplace_back(987);
cout << "The contents of one:";
for(auto& x : one)
{
cout << " " << x;
}
cout << endl;
cout << "The contents of two:";
for(auto& x : two)
{
cout << " " << x;
}
cout << endl;
cout << "The contents of three:";
for(auto& x : three)
{
cout << " " << x;
}
cout << endl;
one.clear();
two.resize(0);
return 0;
}
Operations:
splice
从列表到列表传输元素(公共成员函数)
C++11中有如下原型:
(1) : 将x的所有元素传输到list指定的position中
void splice (const_iterator position, list& x);
void splice (const_iterator position, list&& x);
(2): 仅将i指向的元素从x传输到list指定的position中
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);
(3): 将x范围[first,last]传输到list指定的position中
void splice (const_iterator position, list& x, const_iterator first, const_iterator last);
void splice (const_iterator position, list&& x, const_iterator first, const_iterator last);
remove
删除具有特定值的元素(公共成员函数)
remove_if
删除满足条件的元素(公共成员函数模板)
unique
删除重复值(公共成员函数)
merge
合并排序列表(公共成员函数)
sort
对容器中的元素排序(公共成员函数)
reverse
反转元素的顺序(公共成员函数)
/*
list::splice
(1) : 将x的所有元素传输到list指定的position中
void splice (const_iterator position, list& x);
void splice (const_iterator position, list&& x);
(2): 仅将i指向的元素从x传输到list指定的position中
void splice (const_iterator position, list& x, const_iterator i);
void splice (const_iterator position, list&& x, const_iterator i);
(3): 将x范围[first,last]传输到list指定的position中
void splice (const_iterator position, list& x,
const_iterator first, const_iterator last);
void splice (const_iterator position, list&& x,
const_iterator first, const_iterator last);
list::remove
list::remove_if
list::sort
list::reverse
list::unique
list::merge
*/
#include <iostream>
#include <list>
bool is_odd (const int& val) { return (val % 2 == 1); }
int main ()
{
using namespace std;
list<int> mylist1, mylist2;
list<int>::iterator it;
int i = 0;
for(i=1; i<=5; ++i)
{
mylist1.push_back(i); //mylist1: 1, 2, 3, 4, 5
}
for(i=1; i<=5; ++i)
{
mylist2.push_back(i*10); //mylist1: 10, 20, 30, 40, 50
}
it = mylist1.begin();
++it; // "it" 指向 2
mylist1.splice(it, mylist2); // mylist1: 1 10 20 30 40 50 2 3 4 5
//mylist2为空, "it" 依然指向 2
mylist2.splice(mylist2.begin(), mylist1, it); //mylist2: 2
//mylist1: 1 10 20 30 40 50 3 4 5
//"it" 变为无效
it = mylist1.begin();
++it; // "it" 指向 10
mylist2.splice(mylist2.begin(), mylist1, it, mylist1.end()); // mylist2: 10 20 30 40 50 3 4 5 2
// mylist1: 1, "it" 变为无效
cout << "mylist1 :";
for (it=mylist1.begin(); it!=mylist1.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
cout << "mylist2 :";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
mylist2.remove(50); //mylist2: 10 20 30 40 3 4 5 2
mylist2.remove_if(is_odd); //mylist2: 10 20 30 40 4 2
mylist2.push_back(10);
mylist2.push_front(30);
mylist2.sort(); //mylist2: 2 4 10 10 20 30 30 40
cout << "mylist2 :";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
mylist2.unique(); //mylist2: 2 4 10 20 30 40
mylist2.reverse(); //mylist2: 40 30 20 10 4 2
mylist1.merge(mylist2); //mylist2: empty
//mylist1: 1 40 30 20 10 4 2
cout << "mylist1 :";
for (it=mylist1.begin(); it!=mylist1.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
cout << "mylist2 :";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
{
cout << " " << *it;
}
cout << endl;
return 0;
}
Allocator:
get_allocator
获取分配器(公共成员函数)
// list::get_allocator
#include <iostream>
#include <list>
int main ()
{
using namespace std;
list<int> mylist;
int *p;
// allocate
p = mylist.get_allocator().allocate(5);
// assign values
for (int i=0; i<5; ++i)
{
p[i]=i;
}
cout << "The allocated array:";
for (int i=0; i<5; ++i)
{
cout << " " << p[i];
}
cout << endl;
//deallocate
mylist.get_allocator().deallocate(p,5);
return 0;
}