文章目錄
- 1.關于list
- 2.使用
- 2.1 list的構造
- 2.2 list 迭代器的使用
- 2.3 list 容量操作
- 2.3.1 size()
- 2.3.2 empty()
- 2.3.3 resize()
- 2.4 list 元素訪問
- 2.4.1 front()
- 2.4.2 back()
- 2.5 list 修改操作
- 2.5.1 push_front()
- 2.5.2 pop_front()
- 2.5.3 push_back()
- 2.5.4 pop_back()
- 2.5.5 insert()
- 2.5.6 erase()
- 2.5.7 swap()
- 2.5.8 clear()
- 2.6其它
- 2.6.1 remove()
- 2.6.2 remove_if()
- 2.6.3 unique()
- 2.6.4 sort()
- 2.6.5 merge()
- 2.6.6 reverse()
- 3. vector和list對比
1.關于list
? list也是STL提供的一個容器,其底層是一個帶頭雙向循環鏈表,因此,其優缺點如下:
優點:
- 插入和刪除效率高:在鏈表的任意位置插入或刪除元素的時間復雜度為 O (1),這使得
list
在需要頻繁插入和刪除元素的場景下非常高效。 - 內存管理靈活:
list
的元素在內存中不是連續存儲的,因此可以靈活地分配和釋放內存,避免了內存碎片的問題。
缺點:
- 隨機訪問效率低:由于
list
是雙向鏈表,不支持隨機訪問,要訪問第 n 個元素,需要從頭或尾開始遍歷鏈表。 - 空間開銷大:每個元素除了存儲自身的數據外,還需要額外的指針來指向前一個和后一個元素,因此空間開銷較大。
2.使用
? 這里也只介紹常用的一些接口。
2.1 list的構造
1.聲明及說明
構造函數聲明 | 說明 |
---|---|
list(size_type n,const value_type& val = value_type()) | 構造包含n個val元素的list |
list() | 構造空的list |
list(const list& x) | 拷貝構造 |
list (InputIterator ?rst, InputIterator last) | [first,last)區間元素構造 |
2.示例
#include <iostream>
#include <list> //注意包含頭文件<list>
using namespace std;template <class T>
void print_list(list<T>& lt)
{for (auto& e : lt){cout << e << " ";}cout << endl;
}void list_test1()
{list<int> lt1; // 構造空的lt1list<int> lt2(5, 10); // 4個值為10的元素構造lt2list<int> lt3(lt2.begin(), lt2.end()); // 用lt2的[begin(), end())區間構造lt3list<int> lt4(lt3); // 用lt3拷貝構造lt4list<int> lt5{ 1,2,3,4,5 }; //列表格式構造 C++11支持print_list(lt1);// print_list(lt2);//10 10 10 10 10print_list(lt3);//10 10 10 10 10print_list(lt4);//10 10 10 10 10print_list(lt5);//1 2 3 4 5
}int main()
{list_test1();return 0;
}
2.2 list 迭代器的使用
1.聲明及說明
聲明 | 說明 |
---|---|
begin() + end() | 返回第一個元素的迭代器+返回最后一個元素下一個位置的迭代器 |
rbegin() + rend() | 返回反向第一個元素的reverse_iterator,返回反向最后一個元素下一個位置的reverse_iterator |
2.示例
void list_test2()
{list<int> lt{ 1,2,3,4,5 }; //列表格式構造 C++11支持list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;//輸出:1 2 3 4 5list<int>::reverse_iterator rit = lt.rbegin();while (rit != lt.rend()){cout << *rit << " ";++rit;}cout << endl;//輸出:5 4 3 2 1
}int main()
{list_test2();return 0;
}
2.3 list 容量操作
2.3.1 size()
1.聲明及功能
聲明 | 功能 |
---|---|
size_type size() const | 返回list內有效元素個數 |
2.示例
void list_test3()
{list<int> lt{ 1,2,3,4,5 };cout << lt.size() << endl; //5
}int main()
{list_test3();return 0;
}
2.3.2 empty()
1.聲明及功能
聲明 | 功能 |
---|---|
bool empty() const | 檢測list是否為空 |
2.示例
void list_test4()
{list<int> lt1;list<int> lt2{ 1,2,3,4,5 };if (lt1.empty()){cout << "lt1 is empty" << endl;}else{cout << "lt1 is not empty" << endl;}//輸出:lt1 is emptyif (lt2.empty()){cout << "lt2 is empty" << endl;}else{cout << "lt2 is not empty" << endl;}//輸出:lt2 is not empty
}int main()
{list_test4();return 0;
}
2.3.3 resize()
1.聲明及功能
聲明 | 功能 |
---|---|
void resize (size_type n); | 將list的size調整為n。如果n大于當前list的size(),則在列表末尾插入默認構造的元素。如果n小于當前list的size(),則刪除超出n的元素。 |
void resize (size_type n, const value_type& val); | 將list的size調整為n。如果n大于當前列表的size(),則在列表末尾插入足夠數量的值為val的元素。如果n小于當前列表的大小,則刪除超出n的元素。 |
2.示例
void list_test5()
{list<int> lt1(5, 1);list<int> lt2(5, 2);print_list(lt1);//1 1 1 1 1print_list(lt2);//2 2 2 2 2lt1.resize(10, 2);print_list(lt1);//1 1 1 1 1 2 2 2 2 2lt1.resize(2, 0);print_list(lt1);//1 1lt2.resize(1);print_list(lt2);//2lt2.resize(10);print_list(lt2);//2 0 0 0 0 0 0 0 0 0 }int main()
{list_test5();return 0;
}
2.4 list 元素訪問
2.4.1 front()
1.聲明及功能
聲明 | 功能 |
---|---|
reference front(); | 返回list第一個節點的值的引用 |
2.示例
void list_test6()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5++lt.front();//2 2 3 4 5print_list(lt);}
int main()
{list_test6();return 0;
}
2.4.2 back()
1.聲明及功能
聲明 | 功能 |
---|---|
reference back(); | 返回list的最后一個節點中值的引用 |
2.示例
void list_test7()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5--lt.back();print_list(lt);//1 2 3 4 4}
int main()
{list_test7();return 0;
}
2.5 list 修改操作
2.5.1 push_front()
1.聲明及功能
聲明 | 功能 |
---|---|
void push_front (const value_type& val); | 在list首元素前插入值為val的元素 |
2.示例
void list_test8()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5lt.push_front(0);print_list(lt);//0 1 2 3 4 5}
int main()
{list_test8();return 0;
}
2.5.2 pop_front()
1.聲明及功能
聲明 | 功能 |
---|---|
void pop_front(); | 刪除list中第一個元素 |
2.示例
void list_test9()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5 lt.pop_front();print_list(lt);//2 3 4 5}
int main()
{list_test9();return 0;
}
2.5.3 push_back()
1.聲明及功能
聲明 | 功能 |
---|---|
void push_back (const value_type& val); | 在list尾部插入值為val的元素 |
2.示例
void list_test10()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);print_list(lt);//1 2 3 4 5
}
int main()
{list_test10();return 0;
}
2.5.4 pop_back()
1.聲明及功能
聲明 | 功能 |
---|---|
void pop_back(); | 刪除list中最后一個元素 |
2.示例
void list_test11()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5lt.pop_back();lt.pop_back();lt.pop_back();lt.pop_back();print_list(lt);//1}
int main()
{list_test11();return 0;
}
2.5.5 insert()
1.聲明及功能
聲明 | 功能 |
---|---|
iterator insert (iterator position, const value_type& val); | 在position位置前插入值為val的元素 |
void insert (iterator position, size_type n, const value_type& val); | 在position位置前插入n個值為val的元素 |
template < class InputIterator > void insert (iterator position, InputIterator first, InputIterator last); | 在position位置前插入指定區域[first,last)對應值的元素 |
2.示例
void list_test12()
{list<int> lt{ 1,2,3,4,5 };list<int> lt1{ 1,1,1,1,1 };print_list(lt);//1 2 3 4 5list<int>::iterator it = ++lt.begin();lt.insert(it, 0);print_list(lt);//1 0 2 3 4 5lt.insert(lt.begin(), 3, 0);print_list(lt);//0 0 0 1 0 2 3 4 5lt.insert(lt.begin(), lt1.begin(), lt1.end());print_list(lt);//1 1 1 1 1 0 0 0 1 0 2 3 4 5
}
int main()
{list_test12();return 0;
}
2.5.6 erase()
1.聲明及功能
聲明 | 功能 |
---|---|
iterator erase (iterator position); | 刪除position位置的值,并返回position下一個位置的iterator |
iterator erase (iterator first, iterator last); | 刪除指定區間[first,last)的元素并返回last位置的iterator |
2.示例
void list_test13()
{list<int> lt{ 1,2,3,4,5,6,7,8,9,10 };print_list(lt);//1 2 3 4 5 6 7 8 9 10list<int>::iterator it1 = lt.begin();while (it1 != lt.end()){if (*it1 == 5){it1 = lt.erase(it1); //it指向值為6的位置cout << *it1 << endl;//6continue;}it1++;}print_list(lt);//1 2 3 4 5 7 8 9 10list<int>::iterator first = ++lt.begin();//指向2的位置list<int>::iterator last = --lt.end(); //指向10的位置list<int>::iterator it2 = lt.erase(first, last);//刪除[first,last) it2指向last的位置即9的位置cout << *it2 << endl;//10print_list(lt);//1 10
}
int main()
{list_test13();return 0;
}
2.5.7 swap()
1.聲明及功能
聲明 | 功能 |
---|---|
void swap (list& x); | 交換兩個list |
2.示例
void list_test14()
{list<int> lt1{ 1,2,3,4,5 };list<int> lt2{ 5,4,3,2,1 };print_list(lt1);//1 2 3 4 5print_list(lt2);//5 4 3 2 1lt1.swap(lt2);print_list(lt1);//5 4 3 2 1print_list(lt2);//1 2 3 4 5
}
int main()
{list_test14();return 0;
}
2.5.8 clear()
1.聲明及功能
聲明 | 功能 |
---|---|
void clear(); | 清空list中的有效元素(不包括頭節點) |
2.示例
void list_test15()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5lt.clear();print_list(lt);//
}
int main()
{list_test15();return 0;
}
2.6其它
2.6.1 remove()
1.聲明及功能
聲明 | 功能 |
---|---|
void remove (const value_type& val); | 刪除值為val的元素 |
2.示例
void list_test16()
{list<int> lt{ 10,20,30,40,50 };print_list(lt);//10 20 30 40 50lt.remove(30);//有30則刪除print_list(lt);//10 20 40 50lt.remove(1);//無1則不刪除print_list(lt);//10 20 40 50}
int main()
{list_test16();return 0;
}
2.6.2 remove_if()
1.聲明及功能
聲明 | 功能 |
---|---|
template < class Predicate> void remove_if (Predicate pred); | 刪除滿足()中條件的值,其中可以是函數指針或者函數對象 |
2.示例
bool if_even(int n)
{return n % 2 != 0;
}void list_test17()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5lt.remove_if(if_even);//刪除奇數print_list(lt);//2 4
}
int main()
{list_test17();return 0;
}
2.6.3 unique()
1.聲明及功能
聲明 | 功能 |
---|---|
void unique(); | 刪除list中連續重復的值,一段連續值只保留一個(注意區分,不是完全去重) |
2.示例
void list_test18()
{list<int> lt{ 1,1,1,2,2,2,3,3,4,5,5 };print_list(lt);//1 1 1 2 2 2 3 3 4 5 5 lt.unique();//連續重復的數,僅保留一個print_list(lt);//1 2 3 4 5 list<int> lt1{ 1,1,1,2,2,2,1,1,2,2,3,3,4,5,5 };print_list(lt1);1 1 1 2 2 2 1 1 2 2 3 3 4 5 5 lt1.unique();print_list(lt1);//1 2 1 2 3 4 5
}int main()
{list_test18();return 0;
}
2.6.4 sort()
1.聲明及功能
聲明 | 功能 |
---|---|
void sort(); | 默認按升序排序 |
template < class Compare> void sort (Compare comp); | 按comp方法進行排序 |
2.示例
struct cmp
{bool operator()(int a,int b) {return a > b;}
};
void list_test19()
{list<int> lt{ 3,1,2,5,4,0,2 };print_list(lt);//3 1 2 5 4 0 2lt.sort();//默認升序排列print_list(lt);//0 1 2 2 3 4 5lt.sort(cmp());//自定義降序排列print_list(lt);//5 4 3 2 2 1 0
}
int main()
{list_test19();return 0;
}
2.6.5 merge()
1.聲明及功能
聲明 | 功能 |
---|---|
void merge (list& x); | 合并兩個list為一個有序的list(僅適用于兩個已排序的list(升序)) |
2.示例
void list_test20()
{list<int> lt1{ 1,2,6,4,5 };list<int> lt2{ 0,4,21,3,4 };lt1.sort();lt2.sort();lt1.merge(lt2);//將lt2合并到lt1中,合并成一個升序listprint_list(lt1);//0 1 2 3 4 4 4 5 6 21print_list(lt2);//
}
int main()
{list_test20();return 0;
}
2.6.6 reverse()
1.聲明及功能
聲明 | 功能 |
---|---|
void reverse(); | 翻轉list |
2.示例
void list_test21()
{list<int> lt{ 1,2,3,4,5 };print_list(lt);//1 2 3 4 5lt.reverse();print_list(lt);//5 4 3 2 1
}
int main()
{list_test21();return 0;
}
3. vector和list對比
對比 | vector | list |
---|---|---|
底層結構 | 動態順序表 | 帶頭雙向循環鏈表 |
訪問 | 支持隨機訪問,可使用首地址+下標,[]形式 | 不能隨機訪問 |
插入刪除 | 任意位置插入刪除效率較低,需挪動元素 | 任意位置插入刪除效率較高 |
空間利用率 | 底層為連續空間,空間利用率高,緩存利用率高 | 節點動態開辟,容易造成內存碎片,空間利用率低,緩存利用率低 |
迭代器 | 原生態指針 | 指針進行了封裝 |
迭代器失效 | 容器相關操作都可能導致迭代器失效,如插入引起擴容、刪除元素等時 | 插入元素不會導致迭代器失效,刪除節點會導致且只影響當前迭代器 |
使用場景 | 想進行隨機訪問,不關心插入刪除效率時 | 有大量插入刪除場景,不在意隨機訪問效率時 |