日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

stl-list

發(fā)布時間:2025/3/15 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 stl-list 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

1.關于list容器

list是一種序列式容器。list容器完成的功能實際上和數(shù)據(jù)結構中的雙向鏈表是極其相似的,list中的數(shù)據(jù)元素是通過鏈表指針串連成邏輯意義上的線性表,也就是list也具有鏈表的主要優(yōu)點,即:在鏈表的任一位置進行元素的插入、刪除操作都是快速的。list的實現(xiàn)大概是這樣的:list的每個節(jié)點有三個域:前驅(qū)元素指針域、數(shù)據(jù)域和后繼元素指針域。前驅(qū)元素指針域保存了前驅(qū)元素的首地址;數(shù)據(jù)域則是本節(jié)點的數(shù)據(jù);后繼元素指針域則保存了后繼元素的首地址。其實,list和循環(huán)鏈表也有相似的地方,即:頭節(jié)點的前驅(qū)元素指針域保存的是鏈表中尾元素的首地址,list的尾節(jié)點的后繼元素指針域則保存了頭節(jié)點的首地址,這樣,list實際上就構成了一個雙向循環(huán)鏈。由于list元素節(jié)點并不要求在一段連續(xù)的內(nèi)存中,顯然在list中是不支持快速隨機存取的,因此對于迭代器,只能通過“++”或“--”操作將迭代器移動到后繼/前驅(qū)節(jié)點元素處。而不能對迭代器進行+n或-n的操作,這點,是與vector等不同的地方。

?

我想把三個常用的序列式放在一起對比一下是有必要的:

vector :?vector和built-in數(shù)組類似,擁有一段連續(xù)的內(nèi)存空間,能非常好的支持隨即存取,即[]操作符,但由于它的內(nèi)存空間是連續(xù)的,所以在中間進行插入和刪除會造成內(nèi)存塊的拷貝,另外,當插入較多的元素后,預留內(nèi)存空間可能不夠,需要重新申請一塊足夠大的內(nèi)存并把原來的數(shù)據(jù)拷貝到新的內(nèi)存空間。這些影響了vector的效率,但是實際上用的最多的還是vector容器,建議大多數(shù)時候使用vector效率一般是不錯的。vector的用法解析可以參考本人的另一篇隨筆:http://www.cnblogs.com/BeyondAnyTime/archive/2012/08/08/2627666.html

list:??? ??list就是數(shù)據(jù)結構中的雙向鏈表(根據(jù)sgi stl源代碼),因此它的內(nèi)存空間是不連續(xù)的,通過指針來進行數(shù)據(jù)的訪問,這個特點使得它的隨即存取變的非常沒有效率,因此它沒有提供[]操作符的重載。但由于鏈表的特點,它可以以很好的效率支持任意地方的刪除和插入。

deque:?deque是一個double-ended queue,它的具體實現(xiàn)不太清楚,但知道它具有以下兩個特點:它支持[]操作符,也就是支持隨即存取,并且和vector的效率相差無幾,它支持在兩端的操作:push_back,push_front,pop_back,pop_front等,并且在兩端操作上與list的效率也差不多。

?

因此在實際使用時,如何選擇這三個容器中哪一個,應根據(jù)你的需要而定,具體可以遵循下面的原則
1. 如果你需要高效的隨即存取,而不在乎插入和刪除的效率,使用vector
2. 如果你需要大量的插入和刪除,而不關心隨即存取,則應使用list
3. 如果你需要隨即存取,而且關心兩端數(shù)據(jù)的插入和刪除,則應使用deque。

?

2.list中常用的函數(shù)

2.1list中的構造函數(shù):

list() 聲明一個空列表;

list(n) 聲明一個有n個元素的列表,每個元素都是由其默認構造函數(shù)T()構造出來的

list(n,val) 聲明一個由n個元素的列表,每個元素都是由其復制構造函數(shù)T(val)得來的

list(n,val) 聲明一個和上面一樣的列表

list(first,last) 聲明一個列表,其元素的初始值來源于由區(qū)間所指定的序列中的元素


2.2 begin()和end():通過調(diào)用list容器的成員函數(shù)begin()得到一個指向容器起始位置的iterator,可以調(diào)用list容器的 end() 函數(shù)來得到list末端下一位置,相當于:int a[n]中的第n+1個位置a[n],實際上是不存在的,不能訪問,經(jīng)常作為循環(huán)結束判斷結束條件使用。


2.3 push_back() 和push_front():使用list的成員函數(shù)push_back和push_front插入一個元素到list中。其中push_back()從list的末端插入,而 push_front()實現(xiàn)的從list的頭部插入。


2.4 empty():利用empty() 判斷l(xiāng)ist是否為空。


2.5?resize():?如果調(diào)用resize(n)將list的長度改為只容納n個元素,超出的元素將被刪除,如果需要擴展那么調(diào)用默認構造函數(shù)T()將元素加到list末端。如果調(diào)用resize(n,val),則擴展元素要調(diào)用構造函數(shù)T(val)函數(shù)進行元素構造,其余部分相同。


2.6 clear():?清空list中的所有元素。


2.7 front()和back():?通過front()可以獲得list容器中的頭部元素,通過back()可以獲得list容器的最后一個元素。但是有一點要注意,就是list中元素是空的時候,這時候調(diào)用front()和back()會發(fā)生什么呢?實際上會發(fā)生不能正常讀取數(shù)據(jù)的情況,但是這并不報錯,那我們編程序時就要注意了,個人覺得在使用之前最好先調(diào)用empty()函數(shù)判斷l(xiāng)ist是否為空。


2.8 pop_back和pop_front():通過刪除最后一個元素,通過pop_front()刪除第一個元素;序列必須不為空,如果當list為空的時候調(diào)用pop_back()和pop_front()會使程序崩掉。


2.9 assign():具體和vector中的操作類似,也是有兩種情況,第一種是:l1.assign(n,val)將 l1中元素變?yōu)閚個T(val)。第二種情況是:l1.assign(l2.begin(),l2.end())將l2中的從l2.begin()到l2.end()之間的數(shù)值賦值給l1。


2.10 swap():交換兩個鏈表(兩個重載),一個是l1.swap(l2); 另外一個是swap(l1,l2),都可能完成連個鏈表的交換。


2.11 reverse():通過reverse()完成list的逆置。


2.12 merge():合并兩個鏈表并使之默認升序(也可改),l1.merge(l2,greater<int>()); 調(diào)用結束后l2變?yōu)榭?#xff0c;l1中元素包含原來l1 和 l2中的元素,并且排好序,升序。其實默認是升序,greater<int>()可以省略,另外greater<int>()是可以變的,也可以不按升序排列。

?

看一下下面的程序:

1 #include <iostream>2 #include <list>3 4 using namespace std;5 6 int main()7 {8 list<int> l1;9 list<int> l2(2,0); 10 list<int>::iterator iter; 11 l1.push_back(1); 12 l1.push_back(2); 13 l2.push_back(3); 14 l1.merge(l2,greater<int>());//合并后升序排列,實際上默認就是升序 15 for(iter = l1.begin() ; iter != l1.end() ; iter++) 16 { 17 cout<<*iter<<" "; 18 } 19 cout<<endl<<endl; 20 if(l2.empty()) 21 { 22 cout<<"l2 變?yōu)榭?!!"; 23 } 24 cout<<endl<<endl; 25 return 0; 26 }

運行結果:


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():刪除一個元素或一個區(qū)域的元素(兩個重載)

l1.erase(l1.begin()); 將l1的第一個元素刪除。

l1.erase(l1.begin(),l1.end()); 將l1的從begin()到end()之間的元素刪除。

2.15:splice():連接兩個list

總結

以上是生活随笔為你收集整理的stl-list的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。