?個人主頁:?熬夜學編程的小林
💗系列專欄:?【C語言詳解】?【數據結構詳解】【C++詳解】
目錄
1、list的介紹
2、list的使用
2.1、構造函數
2.2、賦值操作符重載
2.3、迭代器使用
2.4、容量操作
2.5、元素訪問
2.6、修改操作
2.7、其他操作
總結
1、list的介紹
1. list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。
2. list的底層是雙向鏈表結構,雙向鏈表中每個元素存儲在互不相關的獨立節點中,在節點中通過指針指向其前一個元素和后一個元素。
3. list與forward_lis非常相似:最主要的不同在于forward_list是單鏈表,只能朝前迭代,已讓其更簡單高效。
4. 與其他的序列式容器相比(array,vector,deque),list?通常在任意位置進行插入、移除元素的執行效率更好。
5. 與其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的隨機訪問,比如:要訪問list的第6個元素,必須從已知的位置(比如頭部或者尾部)迭代到該位置,在這段位置上迭代需要線性的時間開銷;list還需要一些額外的空間,以保存每個節點的相關聯信息(對于存儲類型較小元素的大list來說這可能是一個重要的因素)
因此list的本質就是雙向循環鏈表。
2、list的使用
2.1、構造函數
1. Default constructor (構造一個沒有元素的空容器。)
explicit list (const allocator_type& alloc = allocator_type());
2. Fill constructor? (構造了一個含有 n 個元素的容器,每個元素都是 val 的副本。?)
explicit list (size_type n, const value_type& val = value_type(),const allocator_type& alloc = allocator_type());
3.?Range constructor (使用兩個迭代器 first 和 last,這兩個迭代器指定了一個序列的范圍,來構造一個容器。這個范圍包括從 first 到 last 之間的所有元素,但不包括 last 指向的元素。)
template <class InputIterator>
list (InputIterator first, InputIterator last,const allocator_type& alloc =allocator_type());
4. Copy constructor (構造一個容器,其中包含 x 中每個元素的副本,順序相同。)
list (const list& x);
構造函數( (constructor)) | 接口說明 |
list (size_type n, const value_type& val = value_type()) | 構造的list中包含n個值為val的元素 |
list() | 構造空的list |
list (const list& x) | 拷貝構造函數 |
list (InputIterator first, InputIterator last) | 用[first, last)區間中的元素構造list |
代碼演示:
//構造函數
void test_list1()
{//1.默認構造list<int> lt1;//2.填充構造list<int> lt2(10, 1);//3.范圍構造(迭代器區間構造)vector<int> v = { 1,3,5,6,7,8,9 };list<int> lt3(v.begin(), v.end());//4.拷貝構造list<int> lt4(lt3);}
我們可以通過打斷點的方式查看 list 中元素。
測試結果:
2.2、賦值操作符重載
1. copy (將新內容分配給容器,替換其當前內容,并相應地修改其大小。??)
list& operator= (const list& x);
代碼演示:
void test_list2()
{list<int> lt1(10, 1);list<int> lt2 = lt1;
}
?測試結果:
2.3、迭代器使用
函數聲明 | 接口說明 |
begin + end | 返回第一個元素的迭代器+返回最后一個元素下一個位置的迭代器 |
rbegin + rend | 返回第一個元素的reverse_iterator,即end位置,返回最后一個元素下一個位置的 reverse_iterator,即begin位置 |
此處迭代器指向的位置與vector容器一樣,直接演示代碼!!!
代碼演示:
void test_list3()
{vector<int> v = { 1,2,3,4,5,6,7,8,9 };list<int> lt(v.begin(), v.end());//迭代器區間構造list<int>::iterator it = lt.begin();//獲取指向第一個元素迭代器while (it != lt.end())//正向打印鏈表{cout << *it << " ";//解引用當前位置的值,類似指針解引用it++;//it向后走}cout << endl;auto rit = lt.rbegin();//類型可以直接還用autowhile (rit != lt.rend())//反向打印鏈表{cout << *rit << " ";rit++;}cout << endl;
}
測試結果:?
?
2.4、容量操作
- empty (判斷容器是否為空。)
- size (獲取容器元素個數。)
代碼演示:
void test_list4()
{vector<int> v{ 1,3,5,7,9 };list<int> lt(v.begin(), v.end());cout << "size() = " << lt.size() << endl;cout << "empty() = " << lt.empty() << endl;
}
測試結果:?
【注意】
1. begin與end為正向迭代器,對迭代器執行++操作,迭代器向后移動
2. rbegin(end)與rend(begin)為反向迭代器,對迭代器執行++操作,迭代器向前移動
?
2.5、元素訪問
- front (獲取第一個元素。?)
- back (獲取最后一個元素。)?
代碼演示:
void test_list5()
{vector<int> v{ 2,4,6,8,10 };list<int> lt(v.begin(), v.end());cout << "front() = " << lt.front() << endl;cout << "back() = " << lt.back() << endl;
}
測試結果:?
2.6、修改操作
函數聲明 | 接口說明 |
push_front | 在list首元素前插入值為val的元素 |
pop_front | 刪除list中第一個元素 |
push_back | 在list尾部插入值為val的元素 |
pop_back | 刪除list中最后一個元素 |
?
- push_back (在末尾添加元素。) :
- pop_back? ?(刪除最后一個元素。) :?
代碼演示:
void test_list6()
{list<int> lt;lt.push_back(1);//尾插lt.push_back(2);lt.push_back(3);lt.push_front(10);//頭插lt.push_front(20);lt.push_front(30);
}
測試結果:?
- push_front?(在開頭添加元素。)
- pop_front? ?(刪除第一個元素。)
代碼演示:
void test_list7()
{list<int> lt = { 1,2,3,4,5,6,7 };for (auto x : lt){cout << x << " ";}cout << endl;lt.pop_back();//尾刪lt.pop_front();//頭刪for (auto x : lt){cout << x << " ";}
}
測試結果:?
- insert? ?? ? ? ?(在pos位置前插入元素。)
- erase?? ? ? ? ?(刪除pos位置元素。)?
代碼演示:
void test_list8()
{list<int> lt = { 1,2,3,4,5 };//iterator insert(iterator pos, const T& val);//在pos位置前插入vallt.insert(lt.begin(), 100);//在第一個位置前插入100for (auto x : lt){cout << x << " ";}cout << endl;//iterator erase (iterator pos);//刪除pos位置的值lt.erase(lt.begin());//刪除第一個位置的值for (auto x : lt){cout << x << " ";}cout << endl;
}
測試結果:?
2.7、其他操作
splice?
轉移鏈表元素到另一個鏈表。
代碼演示:
void test_list9()
{list<int> lt;list<int> lt1(1,10);lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);for (auto x : lt1){cout << x << " ";}cout << endl;//將lt鏈表的元素轉移到lt1的第一個位置,轉移的是結點lt1.splice(lt1.begin(), lt);for (auto x : lt1){cout << x << " ";}cout << endl;//lt鏈表的元素全部轉移到lt1中,因此打印為空for (auto x : lt){cout << x << " ";}cout << endl;
}
測試結果:?
remove()
刪除等于val值的元素。
unique()
從容器中每個連續的相等元素組中刪除除第一個元素之外的所有元素。
代碼演示:
void test_list10()
{list<int> lt = { 1,2,3,4,5 };for (auto x : lt){cout << x << " ";}cout << endl;lt.remove(1);//刪除等于1的所有元素for (auto x : lt){cout << x << " ";}cout << endl;//從容器中每個連續的相等元素組中刪除除第一個元素之外的所有元素。lt.unique();for (auto x : lt){cout << x << " ";}cout << endl;
}
?測試結果:
sort()
對列表的元素進行排序,可以接受一個比較函數。
代碼演示:
bool Com(int x, int y)
{return x > y;//降序
}void test_list11()
{list<int> lt = { 1,2,3,3,8,9 };for (auto x : lt){cout << x << " ";}cout << endl;lt.sort(Com);//使用Com排序方法排序,降序for (auto x : lt){cout << x << " ";}cout << endl;
}
?測試結果:
?
reverse()
將鏈表元素進行逆序。
代碼演示:
void test_list12()
{list<int> lt = { 1,2,3,3,8,9 };for (auto x : lt){cout << x << " ";}cout << endl;lt.reverse();//將鏈表逆序for (auto x : lt){cout << x << " ";}cout << endl;
}
測試結果:
總結
本篇博客就結束啦,謝謝大家的觀看,如果公主少年們有好的建議可以留言喔,謝謝大家啦!