list是一個線性雙向鏈表結構,它的數據由若干個節點構成,每一個節點都包括一個信息塊(即實際存儲的數據)、一個前驅指針和一個后驅指針。它無需分配指定的內存大小且可以任意伸縮,這是因為它存儲在非連續的內存空間中,並且由指針將有序的元素鏈接起來。由於其結構的原因,list 隨機檢索的性能非常的不好,因為它不像vector 那樣直接找到元素的地址,而是要從頭一個一個的順序查找,這樣目標元素越靠后,它的檢索時間就越長。檢索時間與目標元素的位置成正比。雖然隨機檢索的速度不夠快,但是它可以迅速地在任何節點進行插入和刪除操作。因為list 的每個節點保存着它在鏈表中的位置,插入或刪除一個元素僅對最多三個元素有所影響,不像vector 會對操作點之后的所有元素的存儲地址都有所影響,這一點是vector 不可比擬的。

list 的特點:
(1) 不使用連續的內存空間這樣可以隨意地進行動態操作;
(2) 可以在內部任何位置快速地插入或刪除,當然也可以在兩端進行push 和pop 。
(3) 不能進行內部的隨機訪問,即不支持[ ] 操作符和vector.at() ;
(4) 相對於verctor 占用更多的內存。
初學list:需要掌握的知識:
(1)定義一個list
(2)向list中加入元素
(3)如何知道list是否為空
(4)如何使用for循環來遍歷一個list
(5)如何使用STL的通用算法for_each來遍歷list
(6)list成員函數begin() 和 end() 以及它們的意義
(7)iterator范圍的概念和一個范圍的最后一個位置實際上並不被處理這一事實
第一:定義,插入,遍歷打印。
代碼實現如下:
#include<stdio.h>
#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
void PrintIt(string& StringToPoint)
{
cout << StringToPoint << endl;
}
int main()
{
list<string> test;
list<string>::iterator testiterator;
test.push_back("no");
test.push_back("march");
test.push_front("ok");
test.push_front("loleina");
test.push_front("begin");
test.push_back("end");
for (testiterator = test.begin(); testiterator != test.end(); ++testiterator)
{
cout << *testiterator << endl;
}
cout << "-------------" << endl;
for_each(test.begin(), test.end(), PrintIt);
cout << "-------------" << endl;
system("PAUSE");
return 0;
}
定義了一個字符串類型的list。需要包含提供STL的 list類的頭文件#include <list>即可;list的成員函數push_back()把一個對象放到一個list的后面,而 push_front()把對象放到前面。
我們想要遍歷一個list,比如打印一個list中的所有對象來看看list上不同操作的結果。要一個元素一個元素的遍歷一個list, 可以這樣做:
A. 這個程序定義了一個iterator(類似指針),testiterator。它指向了這個list的第一個元素。 這可以調用testiterator.begin()來做到,它會返回一個指向list開頭的iterator。然后把它和testiterator.end()的 返回值來做比較,到了那兒的時候就停下來。 容器的end()函數會返回一個指向容器的最后一個位置的iterator。 在上面的例子中,每一次執行for循環,我們就重復引用iterator來得到我們打印的字符串。
注意:不能用testiterator.begin()+2來指向list中的第三個對象,因為STL的list是以雙鏈的list來實現的,所有的數據存放不一定是連續存放的。 它不支持隨機存取。
B.使用STL的通用算法for_each()來遍歷一個iterator的范圍,然后調用PrintIt()來處理每個對象。 不需要初始化、比較和給iterator增量。for_each()完成了這些工作。執行於對象上的操作被很好的 打包在這個函數以外了,不用再做那樣的循環了,代碼更加清晰了。
第二:count()和count_if() 的基本使用
STL的通用算法count()和count_it()用來給容器中的對象記數。就象for_each()一樣,count()和count_if() 算法也是在iterator范圍內來做的。
#include<stdio.h>
#include<iostream>
#include<list>
#include<string>
#include<algorithm>
using namespace std;
class IsLoleina
{
public:
bool operator()(string& name)
{
return name == "loleina";
}
};
int main()
{
list<string> test;
list<int> score;
list<string>::iterator testiterator;
test.push_back("no");
test.push_back("march");
test.push_front("ok");
test.push_front("loleina");
test.push_front("begin");
test.push_back("end");
score.push_back(100);
score.push_back(90);
score.push_back(80);
score.push_back(70);
score.push_back(100);
score.push_back(20);
int countNum(0);
countNum= count(score.begin(), score.end(), 100);
cout << "there are " << countNum << " scores of 100" << endl;
cout << "-------------" << endl;
int countLoleina(0);
countLoleina=count_if(test.begin(), test.end(), IsLoleina());
cout << "there are " << countLoleina << " loleina" << endl;
system("PAUSE");
return 0;
count()算法統計等於某個值的對象的個數。count_if() 帶一個函數對象的參數。函數對象是一個至少帶有一個operator()方法的類。有些STL算法作為參數接收函數對象並調用這個函數對象的operator()方法。函數對象被約定為STL算法調用operator時返回true或false。它們根據這個來判定這個函數。舉個例子會 說的更清楚些。count_if()通過傳遞一個函數對象來作出比count()更加復雜的評估以確定一個對象是否應該被記數。
