list、forward_list、deque的使用
list
双向链表实现的,因此不能使用下标运算符 [] 访问其中的元素
参考:http://www.cplusplus.com/reference/list/list/
类模板声明
template < class T, class Alloc = allocator<T> > class list;
头文件
#include <list>
初始化
//默认无参初始化
explicit list (const allocator_type& alloc = allocator_type());
//n个val填充的初始化
explicit list (size_type n);//没有val,默认的模板类型T的默认值
list (size_type n, const value_type& val,
const allocator_type& alloc = allocator_type());
//迭代器范围初始化
template <class InputIterator>
list (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
//复制构造
list (const list& x);
list (const list& x, const allocator_type& alloc);
//右值类型的复制构造
list (list&& x);
list (list&& x, const allocator_type& alloc);
//初始化列表
list (initializer_list<value_type> il,
const allocator_type& alloc = allocator_type());
示例
// constructing lists
#include <iostream>
#include <list>
int main ()
{
// constructors used in the same order as described above:
std::list<int> first; // empty list of ints
std::list<int> second (4,100); // four ints with value 100
std::list<int> third (second.begin(),second.end()); // iterating through second
std::list<int> fourth (third); // a copy of third
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
std::list<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
std::cout << "The contents of fifth are: ";
for (std::list<int>::iterator it = fifth.begin(); it != fifth.end(); it++)
std::cout << *it << ' ';
std::cout << '\n';
return 0;
}
插入
- insert:将元素插入到迭代器指向的位置
//向position迭代器指向的位置插入val
iterator insert (const_iterator position, const value_type& val);
//向position迭代器指向的位置插入n个val
iterator insert (const_iterator position, size_type n, const value_type& val);
//将迭代器[first,last)之间的元素插入到position处
template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);
- push_back:在最后一个元素后面插入一个元素
void push_back (const value_type& val);
void push_back (value_type&& val);
- emplace_back:在最后一个元素后面插入一个元素,这个元素被它自身的构造函数构造。一般用于复合类型数据操作。
template <class... Args>
void emplace_back (Args&&... args);
- push_front:在第一个元素前面插入一个元素
void push_front (const value_type& val);
void push_front (value_type&& val);
- emplace_front:在第一个元素前面插入一个元素,这个元素被它自身的构造函数构造。一般用于复合类型数据操作。
template <class... Args>
void emplace_front (Args&&... args);
- assign:为list容器分配新的内容,以代替其原来的内容,并且随之修改容器的大小。
//迭代器范围赋值
template <class InputIterator>
void assign (InputIterator first, InputIterator last);
//n个val填充赋值
void assign (size_type n, const value_type& val);
//初始化列表赋值
void assign (initializer_list<value_type> il);
示例
// list::assign
#include <iostream>
#include <list>
int main ()
{
std::list<int> first;
std::list<int> second;
first.assign (3,100); // 7 ints with value 100
second.assign (first.begin(),first.end()); // a copy of first
int myints[]={1776,7,4,5,8,9,7};
first.assign (myints,myints+7); // assigning from array
std::cout << "Size of first: " << int (first.size()) << '\n';
std::cout << "Size of second: " << int (second.size()) << '\n';
system("pause");
return 0;
}
遍历
函数名 | 作用 |
---|---|
begin | 将迭代器返回到开头 |
end | 将迭代器返回到最后 |
rbegin | 返回一个逆序迭代器,它指向容器的最后一个元素 |
rend | 返回一个逆序迭代器,它指向容器的第一个元素前面的位置 |
- 基于迭代器的遍历
// list::rbegin/rend
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
for (int i=1; i<=5; ++i) mylist.push_back(i);
std::cout << "mylist forwards:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "mylist backwards:";
for (std::list<int>::reverse_iterator rit=mylist.rbegin(); rit!=mylist.rend(); ++rit)
std::cout << ' ' << *rit;
std::cout << '\n';
return 0;
}
- 基于for范围循环的遍历
std::list<int> mylist;
for (int i=1; i<=5; ++i)
mylist.push_back(i);
std::cout << "mylist forwards:";
for (auto& i:mylist)
std::cout << ' ' << i;
std::cout << '\n';
访问
-
front:返回list中第一个元素的引用
-
back:返回list中最后一个元素的引用
// list::front
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist;
mylist.push_back(77);
mylist.push_back(22);
// now front equals 77, and back 22
mylist.front() -= mylist.back();
std::cout << "mylist.front() is now " << mylist.front() << '\n';
return 0;
}
删除
-
pop_front:删除第一个元素
-
pop_back:删除最后一个元素
-
erase:删除迭代器指向位置/范围的元素
iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
- remove:根据值删除元素
void remove (const value_type& val);
- clear():删除容器所有内容
其他成员函数
empty | 容器为空时返回true,否则返回false |
size | 返回当前容器内元素个数 |
max_size | 返回当前容器能容纳的最大元素数量 |
swap | 交换元素 |
resize | 更改容器的容量大小 |
splice | 合并两个 list |
remove_if | 删除满足条件的元素 |
unique | 删除链表中的重复元素 |
merge | 合并排好序的 list |
sort | 链表排序 |
reverse | 将元素反序 |
member type
https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_list.h
582行代码:
public:
typedef _Tp value_type;
typedef typename _Tp_alloc_traits::pointer pointer;
typedef typename _Tp_alloc_traits::const_pointer const_pointer;
typedef typename _Tp_alloc_traits::reference reference;
typedef typename _Tp_alloc_traits::const_reference const_reference;
typedef _List_iterator<_Tp> iterator;
typedef _List_const_iterator<_Tp> const_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef _Alloc allocator_type;
member type | definition | notes |
---|---|---|
value_type | The first template parameter (T) | |
allocator_type | The second template parameter (Alloc) | defaults to: allocator<value_type> |
reference | value_type& | |
const_reference | const value_type& | |
pointer | allocator_traits<allocator_type>::pointer | for the default allocator: value_type* |
const_pointer | allocator_traits<allocator_type>::const_pointer | for the default allocator: const value_type* |
iterator | a bidirectional iterator to value_type | convertible to const_iterator |
const_iterator | a bidirectional iterator to const value_type | |
reverse_iterator | reverse_iterator | |
const_reverse_iterator | reverse_iterator<const_iterator> | |
difference_type | a signed integral type, identical to:iterator_traits::difference_type | usually the same as ptrdiff_t |
size_type | an unsigned integral type that can represent any non-negative value of difference_type | usually the same as size_t |
forward_list
单向链表
它有以下几个属性:
- 潜在可能的非连续内存分配
- 线性时间的元素位置获取
- 常数时间的元素插入、删除、移动
类模板声明
template < class T, class Alloc = allocator<T> > class forward_list;
头文件
#include <forward_list>
初始化
//默认无参构造
explicit forward_list (const allocator_type& alloc = allocator_type());
//n个val填充
explicit forward_list (size_type n);
explicit forward_list (size_type n, const value_type& val,
const allocator_type& alloc = allocator_type());
//迭代器范围构造
template <class InputIterator>
forward_list (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
//复制构造
forward_list (const forward_list& fwdlst);
forward_list (const forward_list& fwdlst, const allocator_type& alloc);
//右值复制构造
forward_list (forward_list&& fwdlst);
forward_list (forward_list&& fwdlst, const allocator_type& alloc);
//初始化列表构造
forward_list (initializer_list<value_type> il,
const allocator_type& alloc = allocator_type());
示例:
// forward_list constructors
#include <iostream>
#include <forward_list>
int main ()
{
// constructors used in the same order as described above:
std::forward_list<int> first; // default: empty
std::forward_list<int> second (3,77); // fill: 3 seventy-sevens
std::forward_list<int> third (second.begin(), second.end()); // range initialization
std::forward_list<int> fourth (third); // copy constructor
std::forward_list<int> fifth (std::move(fourth)); // move ctor. (fourth wasted)
std::forward_list<int> sixth = {3, 52, 25, 90}; // initializer_list constructor
std::cout << "first:" ; for (int& x: first) std::cout << " " << x; std::cout << '\n';
std::cout << "second:"; for (int& x: second) std::cout << " " << x; std::cout << '\n';
std::cout << "third:"; for (int& x: third) std::cout << " " << x; std::cout << '\n';
std::cout << "fourth:"; for (int& x: fourth) std::cout << " " << x; std::cout << '\n';
std::cout << "fifth:"; for (int& x: fifth) std::cout << " " << x; std::cout << '\n';
std::cout << "sixth:"; for (int& x: sixth) std::cout << " " << x; std::cout << '\n';
return 0;
}
插入
-
assign: 为forward_list容器分配新的内容,以代替其原来的内容,并且随之修改容器的大小。
-
emplace_front: 在forward_list容器第一个元素前插入一个元素,这个元素被它自身的构造函数构造。一般用于复合类型数据操作。
-
emplace_after: 在指定位置后面插入一个元素,元素由其构造函数构造。一般用于复合类型数据操作。
-
push_front:在forward_list容器第一个元素前插入一个元素
-
insert_after: 在指定位置后面插入一个或一组元素
// forward_list::insert_after
#include <iostream>
#include <array>
#include <forward_list>
int main ()
{
std::array<int,3> myarray = { 11, 22, 33 };
std::forward_list<int> mylist;
std::forward_list<int>::iterator it;
it = mylist.insert_after ( mylist.before_begin(), 10 ); // 10
// ^ <- it
it = mylist.insert_after ( it, 2, 20 ); // 10 20 20
// ^
it = mylist.insert_after ( it, myarray.begin(), myarray.end() ); // 10 20 20 11 22 33
// ^
it = mylist.begin(); // ^
it = mylist.insert_after ( it, {1,2,3} ); // 10 1 2 3 20 20 11 22 33
// ^
std::cout << "mylist contains:";
for (int& x: mylist) std::cout << ' ' << x;
std::cout << '\n';
return 0;
}
遍历
函数 | 功能 |
---|---|
before_begin | 返回头节点前一个个节点的迭代器 |
begin | 返回指向头节点的迭代器 |
end | 返回指向最后一个节点的迭代器 |
- 基于迭代器的遍历
// forward_list::begin example
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> mylist = { 34, 77, 16, 2 };
std::cout << "mylist contains:";
for ( auto it = mylist.begin(); it != mylist.end(); ++it )
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
- 基于for范围的遍历
// forward_list::begin example
#include <iostream>
#include <forward_list>
int main ()
{
std::forward_list<int> mylist = { 34, 77, 16, 2 };
std::cout << "mylist contains:";
for ( auto i:mylist )
std::cout << ' ' << i;
std::cout << '\n';
return 0;
}
访问
- front:返回第一个节点元素的引用
reference front();
删除
-
pop_front:将forward_list容器的第一个元素删除,size减1
-
erase_after:将指定位置的一个或一组数据删除
-
clear():删除容器forward_list中的所有元素
其他
函数 | 功能 |
---|---|
empty | 测试forward_list容器是否为空。返回值类型为bool,如果为空返回true,否则返回false |
swap | 交换两个forward_list容器的内容 |
max_size | 返回forward_list容器能存储元素的最大个数 |
resize | 重新设置forward_list容器的大小。如果设置的值n小于当前容器的容量,则只取容器前n个元素;如果n大于当前容器的容量且给定了指定填充值,则将容器扩展到容量为n,并用填充值填充,否则用默认构造函数值填充 |
splice_after | 将一个链表整体插入到另一个链表中由迭代器指向的元素后面 |
remove | 从单向链表中移除等于某个值的结点 |
unique | 移除单向链表中重复的结点 |
merge | 合并两个有序链表 |
sort | 排序链表 |
reverse | 逆转链表 |
deque
deque双向队列是一种双向开口的连续线性空间,它由一段一段的定量连续空间构成。一旦有必要在deque的前端或尾端增加新空间,便配置一段定量连续空间,串接在整个deque的头端或尾端。deque最大任务就是在这些分段的定量连续空间上,维护整体连续的假象。
deque可以高效的在头尾两端插入和删除元素,头尾两端分别做插入和删除操作都是常数时间
deque: 是一个double-ended queue,
1)支持随即存取,也就是[]操作符,
2)支持两端操作,push(pop)-back(front),在两端操作上与list效率差不多
在实际使用时,选择vector、list、deque三个容器中哪一个,应根据你的需要而定,一般应遵循下面的原则:
1、如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2、如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3、如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque。
类模板声明
template < class T, class Alloc = allocator<T> > class deque;
头文件
#include <deque>
初始化
//默认无参构造
explicit deque (const allocator_type& alloc = allocator_type());
//n个val填充
explicit deque (size_type n);
deque (size_type n, const value_type& val,
const allocator_type& alloc = allocator_type());
//迭代器范围构造
template <class InputIterator>
deque (InputIterator first, InputIterator last,
const allocator_type& alloc = allocator_type());
//复制构造
deque (const deque& x);
deque (const deque& x, const allocator_type& alloc);
//右值移动语义构造
deque (deque&& x);
deque (deque&& x, const allocator_type& alloc);
//初始化列表构造
deque (initializer_list<value_type> il,
const allocator_type& alloc = allocator_type());
// constructing deques
#include <iostream>
#include <deque>
int main ()
{
unsigned int i;
// constructors used in the same order as described above:
std::deque<int> first; // empty deque of ints
std::deque<int> second (4,100); // four ints with value 100
std::deque<int> third (second.begin(),second.end()); // iterating through second
std::deque<int> fourth (third); // a copy of third
// the iterator constructor can be used to copy arrays:
int myints[] = {16,2,77,29};
std::deque<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
std::cout << "The contents of fifth are:";
for (std::deque<int>::iterator it = fifth.begin(); it!=fifth.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
插入
- assign:
//[first,last)范围内的值赋值给deque容器
template <class InputIterator>
void assign (InputIterator first, InputIterator last);
//n个val值赋值给deque容器
void assign (size_type n, const value_type& val);
- push_back:最后一个元素后添加一个值
void push_back (const value_type& val);
void push_back (value_type&& val);
- emplace_back:向deque容器最后一个元素后插入一个元素,这个元素被它自身的构造函数构造。一般用于复合类型数据操作。
// deque::emplace_back
#include <iostream>
#include<tuple>
#include <deque>
using namespace std;
int main ()
{
std::deque<tuple<int,string,double> > mydeque = {{0,"zero",0.0}};
mydeque.emplace_back (1,"one",1.1);
mydeque.emplace_back (2,"two",2.2);
std::cout << "mydeque contains:"<<endl;
for (auto& x: mydeque)
std::cout << get<0>(x)<<' '<<get<1>(x)<<' '<<get<2>(x)<<endl;
std::cout << '\n';
return 0;
}
-
push_front:第一个元素之前插入一个值
-
emplace_front:向deque容器第一个元素前插入一个元素,这个元素被它自身的构造函数构造。一般用于复合类型数据操作。
-
insert:在迭代器指定的位置插入
//向迭代器position指向的位置插入val值
iterator insert (const_iterator position, const value_type& val);
//向迭代器position指向的位置插入n个val值
iterator insert (const_iterator position, size_type n, const value_type& val);
//向迭代器position指向的位置插入[first,last)范围内的值
template <class InputIterator>
iterator insert (const_iterator position, InputIterator first, InputIterator last);
//移动语义
iterator insert (const_iterator position, value_type&& val);
//向迭代器position指向的位置插入初始化列表
iterator insert (const_iterator position, initializer_list<value_type> il);
遍历
函数 | 功能 |
---|---|
begin | 返回指向第一个元素的迭代器 |
end | 返回指向最后一个元素的迭代器 |
rbegin | 返回一个逆序迭代器,它指向容器的最后一个元素 |
rend | 返回一个逆序迭代器,它指向容器的第一个元素前面的位置 |
- 基于迭代器的遍历
// deque::begin
#include <iostream>
#include <deque>
int main ()
{
std::deque<int> mydeque;
for (int i=1; i<=5; i++) mydeque.push_back(i);
std::cout << "mydeque contains:";
for(std::deque<int>::iterator it = mydeque.begin();it!=mydeque.end();it++){
std::cout << ' ' << *it++;
}
std::cout << '\n';
return 0;
}
- 基于for范围的遍历
#include <iostream>
#include <deque>
int main ()
{
std::deque<int> mydeque;
for (int i=1; i<=5; i++) mydeque.push_back(i);
std::cout << "mydeque contains:";
for(auto& i:mydeque){
std::cout << ' ' << i;
}
std::cout << '\n';
return 0;
}
访问
-
operator[]:下标访问,返回下标指向的元素的引用
-
at:同上,下标访问,返回下标指向的元素的引用
-
front:返回第一个元素的引用
-
back:返回最后一个元素的引用
删除
- erase:删除迭代器指向的位置或范围的元素
iterator erase (const_iterator position );
iterator erase (const_iterator first, const_iterator last );
- pop_front:删除第一个位置的元素
void pop_front();
- pop_back:删除最后一个位置的元素
void pop_back();
- clear():删除所有元素
其他
函数 | 功能 |
---|---|
size | 返回容器中元素的个数 |
max_size | 返回容器中最大的容量 |
resize | 重新设置deque容器的大小。如果设置的值n小于当前容器的容量,则只取容器前n个元素;如果n大于当前容器的容量且给定了指定填充值,则将容器扩展到容量为n,并用填充值填充,否则用默认构造函数值填充 |
empty | 容器为空时返回true,否则,返回false |
shrink_to_fit | 使内存分配量适应容器的当前大小size,因为容器实际分配的内存量一般都大于 实际的size) |
swap | 交换两个deque容器的内容 |
// swap deques
#include <iostream>
#include <deque>
main ()
{
unsigned int i;
std::deque<int> foo (3,100); // three ints with a value of 100
std::deque<int> bar (5,200); // five ints with a value of 200
foo.swap(bar);
std::cout << "foo contains:";
for (std::deque<int>::iterator it = foo.begin(); it!=foo.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "bar contains:";
for (std::deque<int>::iterator it = bar.begin(); it!=bar.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}