目錄
1.list的介紹及使用
?1.1.list的構造
1.2 list iterator的使用
1.3.?list capacity?
1.4.list modifiers
1.5.list的迭代器失效
1.list的介紹及使用
list介紹?,可以通過以下圖直觀的感受到 vector 和 list 的區別
Vector?? 插入代價高,但便于排序
List? ?不連續,不能加,但插入的代價特別低
如果需要頻繁隨機訪問元素或在尾部進行插入和刪除操作,可以選擇Vector;
如果需要頻繁在任意位置進行插入和刪除操作,可以選擇List?
list中的接口比較多,此處類似,只需要掌握如何正確的使用,然后再去深入研究背后的原理,已達到可擴展 的能力。以下為list中一些常見的重要接口。
?1.1.list的構造
代碼:
#include<iostream>
#include<list>
using namespace std;
void test1()
{list<int> l1;list<int> l2(4, 100);list<int> l3(l2.begin(), l2.end());list<int> l4(l3);//以數組迭代器構造l5int arr[] = { 116,2,77,29 };list<int> l5(arr, arr + sizeof(arr) / sizeof(int));//列表格式初始化list<int> l6{ 1,2,3,4,5 };//迭代器方法打印auto it = l5.begin();//begin()不要忘記括號了while (it != l5.end()){cout << *it << " ";++it;}cout << endl;//語法糖for (auto e : l3)cout << e << " ";cout << endl;
}
int main()
{test1();cin.get();return 0;
}
?
1.2 list iterator的使用
此處,大家可暫時將迭代器理解成一個指針,該指針指向list中的某個節點。
?
代碼:
void test2()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));// 使用正向迭代器正向list中的元素// list<int>::iterator it = l.begin(); // C++98中語法auto it = l.begin(); // C++11之后推薦寫法while (it != l.end()){cout << *it << " ";++it;}cout << endl;// 使用反向迭代器逆向打印list中的元素// list<int>::reverse_iterator rit = l.rbegin();auto rit = l.rbegin();while (rit != l.rend()){cout << *rit << " ";++rit;}cout << endl;
}
【注意】
1. begin與end為正向迭代器,對迭代器執行++操作,迭代器向后移動
2. rbegin(end)與rend(begin)為反向迭代器,對迭代器執行++操作,迭代器向前移動 ?
1.3.?list capacity?
list element access
1.4.list modifiers
ps:? vector就沒有頭插和頭刪
void test3()
{int arr[] = { 1, 2, 3 };list<int> L(arr, arr + sizeof(arr) / sizeof(int));print(L);//尾插4,頭插0//刪除尾部和頭部節點L.push_back(4);L.push_front(0);print(L);L.pop_back();L.pop_front();print(L);//insert/erase//獲取鏈表中的第二個元素auto pos = ++L.begin();//pos前插入4L.insert(pos, 4);//pos前插入5個元素為5的數值L.insert(pos, 5, 3);print(L);//在pos前插入v.begin、v.end之間的元素vector<int> v{ 7, 8, 9 };L.insert(pos, v.begin(), v.end());print(L);//刪除pos上的元素L.erase(pos);print(L);//刪除list中的所有元素L.clear();print(L);
}
注意:
pos
?是指向最初的第二個節點的位置的迭代器。當調用?L.erase(pos);
?時,實際上是刪除了?pos
?所指向的節點,而不是刪除?pos
?這個迭代器本身。
1.5.list的迭代器失效
前面說過,此處大家可將迭代器暫時理解成類似于指針,迭代器失效即迭代器所指向的節點的無效,即該節 點被刪除了。因為list的底層結構為帶頭結點的雙向循環鏈表,因此在list中進行插入時是不會導致list的迭代 器失效的,只有在刪除時才會失效,并且失效的只是指向被刪除節點的迭代器,其他迭代器不會受到影響。
void TestListIterator1()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){// erase()函數執行后,it所指向的節點已被刪除,因此it無效,在下一次使用it時,必須先給其賦值l.erase(it);++it;}
}
// 改正
void test4()
{int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };list<int> l(array, array + sizeof(array) / sizeof(array[0]));auto it = l.begin();while (it != l.end()){l.erase(it++); // it = l.erase(it);//it要++指向下一個}
}
int main()
{//test1();//test2();//test3();test4();cin.get();return 0;
}
2.?list與vector的對比
vector與list都是STL中非常重要的序列式容器,由于兩個容器的底層結構不同,導致其特性以及應用場景不 同,其主要不同如下: