關於STL中list容器的一些總結。本站提示廣大學習愛好者:(關於STL中list容器的一些總結)文章只能為提供參考,不一定能成為您想要的結果。以下是關於STL中list容器的一些總結正文
1.關於list容器
list是一種序列式容器。list容器完成的功效現實上和數據構造中的雙向鏈表是極端類似的,list中的數據元素是經由過程鏈表指針串聯成邏輯意義上的線性表,也就是list也具有鏈表的重要長處,即:在鏈表的任一名置停止元素的拔出、刪除操作都是疾速的。list的完成年夜概是如許的:list的每一個節點有三個域:先驅元素指針域、數據域和後繼元素指針域。先驅元素指針域保留了先驅元素的首地址;數據域則是本節點的數據;後繼元素指針域則保留了後繼元素的首地址。其實,list和輪回鏈表也有類似的處所,即:頭節點的先驅元素指針域保留的是鏈表中尾元素的首地址,list的尾節點的後繼元素指針域則保留了頭節點的首地址,如許,list現實上就組成了一個雙向輪回鏈。因為list元素節點其實不請求在一段持續的內存中,明顯在list中是不支撐疾速隨機存取的,是以關於迭代器,只能經由過程“++”或“--”操作將迭代器挪動到後繼/先驅節點元素處。而不克不及對迭代器停止+n或-n的操作,這點,是與vector等分歧的處所。
我想把三個經常使用的序列式放在一路比較一下是有需要的:
vector :vector和built-in數組相似,具有一段持續的內存空間,能異常好的支撐隨即存取,即[]操作符,但因為它的內存空間是持續的,所以在中央停止拔出和刪除會形成內存塊的拷貝,別的,當拔出較多的元素後,預留內存空間能夠不敷,須要從新請求一塊足夠年夜的內存並把本來的數據拷貝到新的內存空間。這些影響了vector的效力,然則現實上用的最多的照樣vector容器,建議年夜多半時刻應用vector效力普通是不錯的。
list:list就是數據構造中的雙向鏈表(依據sgi stl源代碼),是以它的內存空間是不持續的,經由過程指針來停止數據的拜訪,這個特色使得它的隨即存取變的異常沒有用率,是以它沒有供給[]操作符的重載。但因為鏈表的特色,它可以以很好的效力支撐隨意率性處所的刪除和拔出。
deque:deque是一個double-ended queue,它的詳細完成不太清晰,但曉得它具有以下兩個特色:它支撐[]操作符,也就是支撐隨即存取,而且和vector的效力相差無幾,它支撐在兩頭的操作:push_back,push_front,pop_back,pop_front等,而且在兩頭操作上與list的效力也差不多。
是以在現實應用時,若何選擇這三個容器中哪個,應依據你的須要而定,詳細可以遵守上面的准繩:
1. 假如你須要高效的隨即存取,而不在意拔出和刪除的效力,應用vector
2. 假如你須要年夜量的拔出和刪除,而不關懷隨即存取,則應應用list
3. 假如你須要隨即存取,並且關懷兩頭數據的拔出和刪除,則應應用deque。
2.list中經常使用的函數
2.1 list中的結構函數:
list() 聲明一個空列表;
list(n) 聲明一個有n個元素的列表,每一個元素都是由其默許結構函數T()結構出來的
list(n,val) 聲明一個由n個元素的列表,每一個元素都是由其復制結構函數T(val)得來的
list(n,val) 聲明一個和下面一樣的列表
list(first,last) 聲明一個列表,其元素的初始值起源於由區間所指定的序列中的元素
--------------------------------------------------------------------------------
2.2 begin()和end():經由過程挪用list容器的成員函數begin()獲得一個指向容器肇端地位的iterator,可以挪用list容器的 end() 函數來獲得list末尾下一名置,相當於:int a[n]中的第n+1個地位a[n],現實上是不存在的,不克不及拜訪,常常作為輪回停止斷定停止前提應用。
--------------------------------------------------------------------------------
2.3 push_back() 和push_front():應用list的成員函數push_back和push_front拔出一個元素到list中。個中push_back()從list的末尾拔出,而 push_front()完成的從list的頭部拔出。
--------------------------------------------------------------------------------
2.4 empty():應用empty() 斷定list能否為空。
--------------------------------------------------------------------------------
2.5 resize(): 假如挪用resize(n)將list的長度改成只包容n個元素,超越的元素將被刪除,假如須要擴大那末挪用默許結構函數T()將元素加到list末尾。假如挪用resize(n,val),則擴大元素要挪用結構函數T(val)函數停止元素結構,其他部門雷同。
--------------------------------------------------------------------------------
2.6 clear(): 清空list中的一切元素。
--------------------------------------------------------------------------------
2.7 front()和back(): 經由過程front()可以取得list容器中的頭部元素,經由過程back()可以取得list容器的最初一個元素。然則有一點要留意,就是list中元素是空的時刻,這時候候挪用front()和back()會產生甚麼呢?現實上會產生不克不及正常讀取數據的情形,然則這其實不報錯,那我們編法式時就要留意了,小我認為在應用之前最好先挪用empty()函數斷定list能否為空。
--------------------------------------------------------------------------------
2.8 pop_back和pop_front():經由過程刪除最初一個元素,經由過程pop_front()刪除第一個元素;序列必需不為空,假如當list為空的時刻挪用pop_back()和pop_front()會使法式崩失落。
--------------------------------------------------------------------------------
2.9 assign():詳細和vector中的操作相似,也是有兩種情形,第一種是:l1.assign(n,val)將 l1中元素變成n個T(val)。第二種情形是:l1.assign(l2.begin(),l2.end())將l2中的從l2.begin()到l2.end()之間的數值賦值給l1。
--------------------------------------------------------------------------------
2.10 swap():交流兩個鏈表(兩個重載),一個是l1.swap(l2); 別的一個是swap(l1,l2),都能夠完成連個鏈表的交流。
--------------------------------------------------------------------------------
2.11 reverse():經由過程reverse()完成list的逆置。
--------------------------------------------------------------------------------
2.12 merge():歸並兩個鏈表並使之默許升序(也可改),l1.merge(l2,greater<int>()); 挪用停止後l2變成空,l1中元素包括本來l1 和 l2中的元素,而且排好序,升序。其實默許是升序,greater<int>()可以省略,別的greater<int>()是可以變的,也能夠不按升序分列。
看一下上面的法式:
#include <iostream>
#include <list>
using namespace std;
int main()
{
list<int> l1;
list<int> l2(2,0);
list<int>::iterator iter;
l1.push_back(1);
l1.push_back(2);
l2.push_back(3);
l1.merge(l2,greater<int>());//歸並後升序分列,現實上默許就是升序
for(iter = l1.begin() ; iter != l1.end() ; iter++)
{
cout<<*iter<<" ";
}
cout<<endl<<endl;
if(l2.empty())
{
cout<<"l2 變成空 !!";
}
cout<<endl<<endl;
return 0;
}
運轉成果:
2.13 insert():在指定地位拔出一個或多個元素(三個重載):
l1.insert(l1.begin(),100); 在l1的開端地位拔出100。
l1.insert(l1.begin(),2,200); 在l1的開端地位拔出2個100。
l1.insert(l1.begin(),l2.begin(),l2.end());在l1的開端地位拔出l2的從開端到停止的一切地位的元素。
--------------------------------------------------------------------------------
2.14 erase():刪除一個元素或一個區域的元素(兩個重載)
l1.erase(l1.begin()); 將l1的第一個元素刪除。
l1.erase(l1.begin(),l1.end()); 將l1的從begin()到end()之間的元素刪除。