list简介
list被实现为双向链表,list在内存中元素是存放在不同且无关的地址上的,以一个元素为例,通过消耗一些额外的内存保存着两个关联,即前一个元素的关联[如果此元素为第一个元素则关联为空]和下一个元素的关联[如果此元素为最后一个元素则关联为空],可以通过迭代器访问
tips: list的成员函数 remove、unique修改了其关联的基础容器,与泛型算法不同,而merge、splice破坏了其实参,与泛型算法也不同
不使用泛型算法而使用list的成员函数是充分利用list容器的存储结构使这些算法更快速
list的优点
1.可以高效的插入元素和移除在容器中指定条件[remove()、remove_if()]的元素
2.可以通过迭代器以多种顺序来遍历各元素
3.可以高效移动元素/元素块[迭代器对]
list4个构造函数(same as vector and deque)
1.初始化为空的list
2.初始化为n个相同值拷贝的list
3.初始化为一对迭代器之间值的 list [first,last)
4.初始化为用另一个 list 而拷贝的 list [拷贝构造函数]
原型如下:
1.explicit list ( const Allocator& = Allocator() );
2.explicit list ( size_type n, const T& value= T(), const Allocator& = Allocator() );
3.template <class InputIterator>
list ( InputIterator first, InputIterator last, const Allocator& = Allocator() );
4. list ( const list<T,Allocator>& x );
eg:
list <int> first; // empty list of ints
list <int> second (4,100); // four ints with value 100
list <int> third (second.begin(),second.end()); // iterating through second
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};
list <int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
Capacity:
empty | Test whether list is empty |
size | Return size |
max_size | Return maximum size [test winxp 32bit vs2008 value is: 1073741823] |
resize | Change size |
Element access:
front | Access first element |
back | Access last element |
Modifiers:
assign | Assign list content |
push_back | Add element at the end |
pop_back | Delete last element |
insert | Insert elements |
erase | Erase elements |
swap | Swap content//algorithm exists swap, and the same behavior. |
clear | Clear content |
push_front | Insert element at beginning→list and deque unique |
pop_front | Delete first element→list and deque unique |
Operations:→list unique
splice | Move elements from list to list |
remove | Remove elements with specific value//algorithm exists one operating between two iterators. |
remove_if | Remove elements fulfilling condition//same |
unique | Remove duplicate values//same |
merge | Merge sorted lists |
sort | Sort elements in container |
reverse | Reverse the order of elements |
splice
//无序的list合并
1.void splice ( iterator position, list<T,Allocator>& x );
2.void splice ( iterator position, list<T,Allocator>& x, iterator i );
3.void splice ( iterator position, list<T,Allocator>& x, iterator first, iterator last );
//下面是c++ primer上的说明
1.lst.splice(iter,lst2) //lst2拼接到lst中,lst2清空,lst、lst2为不同的list对象
2.lst.splice(iter,lst2,iter2) //只是移动lst2中的iter2对应的元素到lst的iter位置处,lst、lst2可以为相同的list对象
3.lst.splice(iter,beg,end) //移动一个iterator range,beg、end可以为相同的list对象,但是如果移动到的位置iter在beg-end之间,这种运算未定义
2.lst.splice(iter,lst2,iter2) //只是移动lst2中的iter2对应的元素到lst的iter位置处,lst、lst2可以为相同的list对象
3.lst.splice(iter,beg,end) //移动一个iterator range,beg、end可以为相同的list对象,但是如果移动到的位置iter在beg-end之间,这种运算未定义
eg:
list<int> mylist1, mylist2;
list<int>::iterator it;
// set some initial values:
for (int i=1; i<=4; i++)
mylist1.push_back(i); // mylist1: 1 2 3 4
for (int i=1; i<=3; i++)
mylist2.push_back(i*10); // mylist2: 10 20 30
it = mylist1.begin();
++it; // points to 2
mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4
// mylist2 (empty)
// "it" still points to 2 (the 5th element)
mylist2.splice (mylist2.begin(),mylist1, it);
// mylist1: 1 10 20 30 3 4
// mylist2: 2
// "it" is now invalid.
it = mylist1.begin();
advance(it,3); // "it" points now to 30
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
// mylist1: 30 3 4 1 10 20
remove
eg:
int myints[]= {17,89,7,14};
list<int> mylist (myints,myints+4);
mylist.remove(89);
remove_if
eg:
// a predicate implemented as a function:
bool single_digit (const int& value) { return (value<10); }
// a predicate implemented as a class:
class is_odd
{
public:
bool operator() (const int& value) {return (value%2)==1; }
};
int main ()
{
int myints[]= {15,36,7,17,20,39,4,1};
list<int> mylist (myints,myints+8); // 15 36 7 17 20 39 4 1
mylist.remove_if (single_digit); // 15 36 17 20 39
mylist.remove_if (is_odd()); // 36 20
unique
原型如下:
1.void unique ( );
2.template <class BinaryPredicate>
void unique ( BinaryPredicate binary_pred );
eg:
//unique只对已经排好序的容器有效,使用前要先sort
// a binary predicate implemented as a function:
bool same_integral_part (double first, double second)
{ return ( int(first)==int(second) ); }
// a binary predicate implemented as a class:
class is_near
{
public:
bool operator() (double first, double second)
{ return (fabs(first-second)<5.0); }
};
int main ()
{
double mydoubles[]={ 12.15, 2.72, 73.0, 12.77, 3.14,
12.77, 73.35, 72.25, 15.3, 72.25 };
list<double> mylist (mydoubles,mydoubles+10);
mylist.sort(); // 2.72, 3.14, 12.15, 12.77, 12.77,
// 15.3, 72.25, 72.25, 73.0, 73.35
mylist.unique(); // 2.72, 3.14, 12.15, 12.77
// 15.3, 72.25, 73.0, 73.35
mylist.unique (same_integral_part); // 2.72, 3.14, 12.15
// 15.3, 72.25, 73.0
mylist.unique (is_near()); // 2.72, 12.15, 72.25
merge
1.void merge ( list<T,Allocator>& x );
2.template <class Compare>
void merge ( list<T,Allocator>& x, Compare comp );
//将两个有序的list合并到一起。其中后一个list的元素会被清空
eg:
// this compares equal two doubles if
// their interger equivalents are equal
bool mycomparison (double first, double second)
{ return ( int(first)<int(second) ); }
int main ()
{
list<double> first, second;
first.push_back (3.1);
first.push_back (2.2);
first.push_back (2.9);
second.push_back (3.7);
second.push_back (7.1);
second.push_back (1.4);
first.sort();
second.sort();
first.merge(second);
second.push_back (2.1);
first.merge(second,mycomparison);
reverse
eg:
mylist.reverse();
Allocator:
get_allocator
eg:
list<int> mylist;
int * p;
unsigned int i;
// allocate an array of 5 elements using mylist's allocator:
p=mylist.get_allocator().allocate(5);
// assign some values to array
for (i=0; i<5; i++) p[i]=i;
cout << "The allocated array contains:";
for (i=0; i<5; i++) cout << " " << p[i];
cout << endl;
mylist.get_allocator().deallocate(p,5);
Output:
The allocated array contains: 0 1 2 3 4