std::list
<list>
列表性質
1、雙向連結串列
2、只支援雙向順序訪問,不支援下標訪問(隨機訪問迭代器)(元素隨機訪問)
3、因為不支援隨機訪問迭代器,所以不能使用std::sort
進行排序,需要呼叫成員函式list::sort
4、在list
中任何位置進行插入/刪除
操作速度都很快
容器操作
1、型別別名
型別 | 解釋 |
---|---|
iterator |
此容器型別的迭代器型別 |
const_iterator |
可以讀取元素,但不能修改元素的迭代器型別 |
size_type |
無符號整數型別,足夠儲存此種容器型別最大可能容器的大小 |
difference_type |
帶符號整數型別,足夠儲存兩個迭代器之間的距離 |
value_type |
元素型別 |
reference |
元素的左值型別;與value_type& 含義相同 |
const_reference |
元素的左值型別,(即const value_type& ) |
2、構造列表
1)、預設構造
構造一個沒有任何元素的空容器
list<int> mylist;
2)、填充構造
構造一個含有 n 個元素的容器, 每一個元素被賦值為 val(如果存在 val)
list<type> mylist( size_type n, const value_type &val );
list<int> mylist (5); // 含有 5 個元素,每個元素都被執行了預設初始化 (0)
list<int> mylist ( 5, 1314 ); // 含有 5 個元素,每個元素的值都是 1314
3)、範圍構造
構造一個容器,具有和範圍 [ first, last ) 一樣多數量的元素,並且容器內元素順序與範圍內元素順序對應
list<type> mylist( Iterator first, Iterator last );
int myints[5] = { 75, 23, 65, 42, 13 };
list<int> mylist ( myints, myints + 5 ); // 構造一個 list 容器,元素為 myints 內的元素的副本
4)、拷貝構造
構造一個與mylist
中的元素與元素順序相同的容器
list<type> yourlist( const list &mylist );
list<int> mylist (5, 1314);
list<int> yourlist ( mylist ); // 將 mylist 的元素拷貝給 yourlist
5)、列表構造(列表元素初始化)
構造一個與il
中的元素與元素順序相同的容器,initializer_list
即{ }
list<type> mylist( initializer_list<value_type> il );
/* 三種寫法相同 */
list<int> mylist ( {1, 3, 5} ); //mylist 內的元素為1, 3, 5
list<int> mylist {1, 3, 5};
list<int> mylist = {1, 3, 5}; // 下文 `賦值`中會說明‘=’的作用
3、賦值 (=
)
1)拷貝
將 列表x
拷貝給 列表mylist
mylist = const list &x;
list<int> mylist ( {1, 3, 5} );
// 不需要提前給 x 分配大小 因為 ‘=’ 會把 mylist 中的元素資訊全部拷貝過去
list<int> x;
x = mylist;
2)列表拷貝
通過列表拷貝 initializer_list
即{ }
mylist = initializer_list<value_type> il;
list<int> mylist(3);
// 注意要為 mylist 分配大小
mylist = {1, 2, 3};
4、迭代器
1)begin
返回指向容器第一個元素的迭代器
2)end
返回一個尾後迭代器,指向尾元素的下一個位置
用法舉例:
#include <iostream>
#include <list>
using namespace std;
int main ( void )
{
list<int> lk;
for ( int i = 1; i <= 5; i++ ) // 1, 2, 3, 4, 5
lk.push_back(i);
for ( auto i = lk.begin(); i != lk.end(); i++ )
cout << *i << " ";
cout << endl;
return 0;
}
4)cbegin
返回的迭代器型別為
const_iterator
所以不可以對迭代器解引用修改
5)cend
返回的迭代器型別為
const_iterator
所以不可以對迭代器解引用修改
5)rbegin
返回指向容器的尾元素之前位置的迭代器
6)rend
返回指向容器首元素之前位置的迭代器
7)crbegin
返回
const_iterator
8)crend
返回
const_iterator
5、空間
1)empty
返回當前容器是否為空
2)size
容器中元素的數目
3)max_size
容器可儲存的最大元素數目
6、訪問元素
1)front
返回對
list
容器的第一個元素的引用
2)back
返回對
list
容器的最後一個元素的引用
7、修改
1)assign
assign
也是一種賦值方式,和初始化
與賦值
不同的是:assign
允許我們從一個不同但相容型別賦值,或者從容器的一個子序列賦值。
assign
操作用引數所指定的元素(的拷貝)替換左邊容器中的所有元素。
例如,我們可以用assign
實現將一個vector
中的一段char*
值賦予一個list
中的string
:
#include <iostream>
#include <list>
#include <vector>
using namespace std;
int main ( void )
{
list<string> myString;
vector<char*> myChar;
myChar.push_back ( "1 2 3 4 5 6" );
myChar.push_back ( "7 8 9 10" );
myChar.push_back ( "11 12 13 14" );
myString.assign ( myChar.begin(), myChar.end() ); //可以將 char* 轉換為 string
for ( auto i = myString.begin(); i != myString.end(); i++ )
{
cout << *i << ' ';
}
cout << endl;
return 0;
}
這段程式碼中對assign
的呼叫將names
中的元素替換為迭代器指定的範圍中的元素的拷貝。
assign
的引數決定了容器中將有多少個元素以及它們的值都是什麼。
輸出
型別 | 解釋 |
---|---|
val |
待插入元素的值 |
n |
新的容器尺寸 |
first, last |
指定元素範圍的迭代器,將 [first,last)範圍內的所有元素拷貝到list容器中 |
il |
一個列表元素,相當於列表初始化 |
(1)範圍賦予
void assign ( InputIterator first, InputIterator last );
(2)填充賦予
接受一個整數值和一個元素值。它用指定數目且具有相同給定值的元素替換容器中原有的元素
void assign ( size_type n, const value_type &val );
(3)列表元素賦予
接受一段元素列表,將list
容器中的元素和大小按序替換為該元素列表內的值和個數
void assign ( initializer_list<value_type> il );
2)emplace
3)emplace_front
void emplace_front ( Args&&... args );
4)emplace_back
void emplace_back ( Args&&... args );
來救救蒟蒻吧,emplace
沒學懂,歡迎留言補充交流
5)push_front
在list
容器的頭部建立一個值為val
的元素,相應地使size
增大了1
void push_front ( const value_type &val );
6)pop_front
刪除list
容器的的首元素
void pop_front ( void );
7)push_back
在list
容器的尾部建立一個值為val
的元素,相應地使size
增大了1
void push_back ( const value_type &val );
8)pop_back
刪除list
容器的的尾元素
void pop_back ( void );
9)insert
型別 | 解釋 |
---|---|
position |
在容器中插入新元素的位置,新元素將插入在position 的前面 |
val |
待插入元素的值 |
n |
要插入的元素個數,每個數的值都是val |
first, last |
指定元素範圍的迭代器,將 [first,last)範圍內的所有元素副本插入到position 的前面 |
il |
將列表{ } 內的值插入到position 的前面 |
(1)插入單個元素
在迭代器position
指向的元素之前建立一個值為val
的元素,返回指向新新增的元素的迭代器
iterator insert ( const_iterator position, const value_type& val );
(2)插入 n 個相同元素
在迭代器position
指向的元素之前插入n
個值為val
的元素,返回指向新新增的一個元素的迭代器;若n
為0
,則返回p
iterator insert ( const_iterator position, size_type n, const value_type& val );
(3)插入元素值列表 { a, b, c, ... }
il
是一個花括號包圍的元素值列表。將這些給定值插入到迭代器position
指向的元素之前。返回指向新新增的第一個元素的迭代器;若列表為空,則返回p
iterator insert (const_iterator position, initializer_list<value_type> il);
10)erase
a.刪除單個元素
刪除由一個迭代器指定的單個元素
返回指向刪除的元素之後位置的迭代器
iterator erase ( const_iterator position );
b.刪除多個元素
接受一對迭代器,允許我們刪除一個範圍內的元素
迭代器first
指向要刪除的第一個元素,last
指向我們要刪除的最後一個元素之後的位置
iterator erase ( const_iterator first, const_iterator last );
11)swap
用於交換容器內容,swap
交換兩個list
容器內部的資料結構(元素本身並未交換),所以非常快,可以保證在常數時間內完成。
void swap ( list &x );
12)resize
將容器的大小變為n
1、如果n
小於當前容器的大小,則將元素個數減少到前n個元素,並刪除超出範圍的元素。
2、如果n
大於當前容器的大小,則通過在末尾插入任意數量的元素以達到n個元素。
如果指定了val
,則將新元素初始化為val
的副本,否則,將對它們進行值的預設初始化。
void resize ( size_type n, value_type val = value_type() );
13)clear
刪除list容器中所有元素
void clear ( void )
8、操作
1)splice
例如有list
a,list
b
則splice
的作用是將b
中的某些元素移動
到a
當中的某個位置去
a.移動所有元素
將x
容器中的所有元素移動到指定容器的迭代器position
所指向的位置。
插入的第一個元素置於迭代器position
所指向的位置
原先位置的元素置於被插入的最後一個元素的後面。(兩容器的大小均已改變)
注意和insert
的區別,splice
相當是把元素插入在了position
的前面
void splice ( iterator position, list &x );
c.單一元素移動
將x
容器中,迭代器i
所指向的元素移動到list
容器中,迭代器position
所指向的位置之前.
void splice (iterator position, list& x, iterator i);
c.範圍元素移動
將範圍[first,last)
內的元素從x
移動到list
容器中position
所指向的位置之前。
void splice (iterator position, list& x, iterator first, iterator last);
關於splice
的具體操作請見程式碼:
// splicing lists
#include <iostream>
#include <list>
int main ()
{
std::list<int> mylist1, mylist2;
std::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();
std::advance(it,3); // "it" points now to 30
mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());
// mylist1: 30 3 4 1 10 20
std::cout << "mylist1 contains:";
for (it=mylist1.begin(); it!=mylist1.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
std::cout << "mylist2 contains:";
for (it=mylist2.begin(); it!=mylist2.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
OutPut:
mylist1 contains: 30 3 4 1 10 20
mylist2 contains: 2
以上程式碼源於http://www.cplusplus.com/reference/list/list/splice/
2)remove
刪除具有val
的元素
void remove ( const value_type &val );
3)remove_if
刪除滿足條件的元素
void remove_if ( Predicate pred );
程式碼說明一切
// list::remove_if
#include <iostream>
#include <list>
// a predicate implemented as a function:
bool single_digit (const int& value) { return (value<10); }
// a predicate implemented as a class:
struct is_odd {
bool operator() (const int& value) { return (value%2)==1; }
};
int main ()
{
int myints[]= {15,36,7,17,20,39,4,1};
std::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
std::cout << "mylist contains:";
for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
OutPut:
mylist contains: 36 20
以上程式碼源於http://www.cplusplus.com/reference/list/list/remove_if/
4)unique
刪除相鄰重重元素,是真的銷燬掉.
void unique ( void );
5)merge
拼接list
容器
a.拼接
void merge ( list &x );
b.帶有比較模板的拼接
void merge ( list& x, Compare comp );
6)sort
對list
容器進行排序
a.升序排序 // 0, 1, 2, 3, 4
void sort ( void );
b.cmp
模板排序
void sort ( Compare comp );
7)reverse
反轉list
容器中元素的順序
void reverse ( void );