閱讀導航
- 前言
- 一、list簡介
- 1.概念
- 2.特點
- 二、list的使用
- 1.list的構造
- 2.常見的操作
- ?std::list類型的增、刪、查、改
- 三、list與vector的對比
- 溫馨提示
前言
文章綁定了VS平臺下std::list的源碼,大家可以下載了解一下😍
前面我們講了C語言的基礎知識,也了解了一些數據結構,并且講了有關C++的命名空間的一些知識點以及關于C++的缺省參數、函數重載,引用 和 內聯函數也認識了什么是類和對象以及怎么去new一個 ‘對象’ ,以及學習了幾個STL的結構也相信大家都掌握的不錯,接下來博主將會帶領大家繼續學習有關C++比較重要的知識點—— list(STL)。下面話不多說坐穩扶好咱們要開車了😍
一、list簡介
1.概念
std::list是C++標準庫中的雙向鏈表容器。(這里有官方介紹鏈接) 它支持在任意位置進行快速插入和刪除操作,并且在需要對元素進行頻繁的插入和刪除操作時,通常比std::vector更高效。std::list的元素不是在連續內存中存儲,而是通過指針相互連接在一起。
2.特點
-
雙向訪問:std::list的元素可以通過雙向迭代器從前向后或者從后向前進行訪問。
-
插入和刪除操作高效:由于std::list的元素是通過指針連接在一起的,插入和刪除操作只需要修改相鄰元素的指針,因此在任意位置進行插入和刪除操作的時間復雜度是O(1)。
-
不支持隨機訪問:由于std::list的元素不是在連續內存中存儲的,因此不能通過下標來隨機訪問元素。如果需要隨機訪問元素,可以考慮使用std::vector或者std::array。
-
內存占用相對較大:由于每個元素都需要額外的指針來連接其他元素,std::list的內存占用相對較大。
二、list的使用
list 中的接口比較多,此處類似,只需要掌握如何正確的使用,然后再去深入研究背后的原理,已達到可擴展的能力。以下為list中一些常見的重要接口。
1.list的構造
std::list類提供了多個構造函數,用于創建和初始化std::list對象。官方鏈接點這里跳轉 下面是常用的構造函數列表:
-
默認構造函數:
std::list<T> myList;
創建一個空的std::list對象,其中T是元素的類型。
-
帶有容量參數的構造函數:
std::list<T> myList(size, value);
創建一個包含size個元素的std::list對象,每個元素的值都是value。
-
區間構造函數:
std::list<T> myList(first, last);
創建一個std::list對象,其中包含[first, last)區間的元素。first和last是輸入迭代器,用于指定要拷貝到新std::list中的元素范圍。
-
拷貝構造函數:
std::list<T> myList(otherList);
創建一個std::list對象,其中包含與otherList相同的元素。這將執行深拷貝,即將otherList中的元素復制到新的std::list對象中。
-
移動構造函數:
std::list<T> myList(std::move(otherList));
創建一個std::list對象,并從其他std::list對象otherList中移動元素到新的std::list對象中。在移動構造函數后,otherList將為空。
注意:上述構造函數中的T表示元素的類型,可以是任何有效的C++類型。
#include <list>int main() {// 默認構造函數std::list<int> myList;// 帶有容量參數的構造函數std::list<int> myList2(5, 10); // 包含5個值為10的元素// 區間構造函數int arr[] = {1, 2, 3, 4, 5};std::list<int> myList3(std::begin(arr), std::end(arr)); // 包含數組arr的元素// 拷貝構造函數std::list<int> myList4(myList2);// 移動構造函數std::list<int> myList5(std::move(myList4)); // myList4將為空return 0;
}
這些是std::list常用的構造函數示例。你可以根據自己的需求選擇適當的構造函數來創建std::list對象。
2.常見的操作
?std::list類型的增、刪、查、改
-
插入元素:
- push_back(value):在列表的末尾插入一個元素。
- push_front(value):在列表的開頭插入一個元素。
- insert(pos, value):在指定位置pos之前插入一個元素。
-
刪除元素:
- pop_back():刪除列表末尾的元素。
- pop_front():刪除列表開頭的元素。
- erase(pos):刪除指定位置pos處的元素。
- erase(first, last):刪除從[first, last)范圍內的所有元素。
-
訪問元素:
- front():返回列表的第一個元素的引用。
- back():返回列表的最后一個元素的引用。
-
迭代器操作:
- begin():返回指向列表第一個元素的迭代器。
- end():返回指向最后一個元素之后位置的迭代器。
- rbegin():返回指向列表最后一個元素的逆向迭代器。
- rend():返回指向第一個元素之前位置的逆向迭代器。
-
大小和清空操作:
- size():返回列表中元素的數量。
- empty():檢查列表是否為空。
- clear():清除列表中的所有元素。
-
修改元素:
- assign(first, last):用[first, last)范圍內的元素替換列表的內容。
- assign(n, value):用n個值為value的元素替換列表的內容。
- resize(count):改變列表的大小,使其包含count個元素,并根據需要插入或刪除元素。
- swap(otherList):交換當前列表與otherList之間的內容。
-
查找和排序:
- find(value):返回指向第一個值為value的元素的迭代器;如果找不到,則返回end()。
- sort():按升序對列表中的元素進行排序。
- reverse():反轉列表中的元素的順序。
以上只是std::list的一些常見操作,還有很多其他的成員函數可用于更復雜的操作。這里有官方的鏈接你可以根據具體的需求選擇適當的操作。
以下是一些示例,展示了std::list的常見操作:
#include <list>
#include <iostream>int main() {std::list<int> myList;// 插入元素myList.push_back(1);myList.push_front(2);myList.insert(std::next(myList.begin()), 3);// 刪除元素myList.pop_back();myList.pop_front();myList.erase(std::next(myList.begin()));// 訪問元素std::cout << "Front element: " << myList.front() << std::endl;std::cout << "Back element: " << myList.back() << std::endl;// 迭代器操作for (auto it = myList.begin(); it != myList.end(); ++it) {std::cout << *it << " ";}std::cout << std::endl;// 大小和清空操作std::cout << "Size: " << myList.size() << std::endl;std::cout << "Empty: " << (myList.empty() ? "Yes" : "No") << std::endl;myList.clear();// 查找和排序myList.push_back(5);myList.push_back(2);myList.push_back(4);myList.push_back(1);auto it = myList.find(4);ifit != myList.end()) {std::cout << "Found value 4" << std::endl;}myList.sort();std::cout << "Sorted list: ";for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;return 0;
}
三、list與vector的對比
-
數據存儲方式:
- vector:使用連續的內存塊存儲,可以在O(1)時間內訪問任意位置的元素。
- list:使用雙向鏈表存儲,每個節點存儲一個元素,在O(n)時間內訪問任意位置的元素。
-
動態性:
- vector:動態數組,長度可變。能夠動態增長和收縮,但在插入和刪除操作時可能需要重新分配內存,導致數據的搬移。
- list:由于使用鏈表存儲,插入和刪除操作相對快速,不會涉及內存的重新分配和數據的搬移。
-
訪問效率:
- vector:由于數據存儲在連續的內存塊中,可以通過下標訪問元素,提供了O(1)的隨機訪問效率。
- list:需要遍歷鏈表才能訪問到指定位置的元素,訪問效率為O(n)。
-
插入和刪除操作:
- vector:在尾部進行插入和刪除操作效率高,復雜度為O(1);在中間或頭部進行插入和刪除操作會導致后續元素的移動,復雜度為O(n)。
- list:在插入和刪除操作時,只需修改相鄰節點的指針,復雜度為O(1),對于任意位置的插入和刪除都具有較高效率。
-
內存使用:
- vector:由于數據存儲在連續的內存塊,相對于list可能產生更少的內存開銷。
- list:由于每個元素需要額外的指針進行連接,相對于vector可能產生更多的內存開銷。
綜上所述,當需要頻繁進行隨機訪問操作或者需要動態增長和收縮容量時,vector是一個更好的選擇。而在需要頻繁進行插入和刪除操作、對訪問效率要求不高或者需要避免數據搬移時,list是一個更合適的選擇。
溫馨提示
感謝您對博主文章的關注與支持!在閱讀本篇文章的同時,我們想提醒您留下您寶貴的意見和反饋。如果您喜歡這篇文章,可以點贊、評論和分享給您的同學,這將對我提供巨大的鼓勵和支持。另外,我計劃在未來的更新中持續探討與本文相關的內容。我會為您帶來更多關于C++以及編程技術問題的深入解析、應用案例和趣味玩法等。請繼續關注博主的更新,不要錯過任何精彩內容!
再次感謝您的支持和關注。我們期待與您建立更緊密的互動,共同探索C++、算法和編程的奧秘。祝您生活愉快,排便順暢!