CPP中的List

一.list的介紹:

? 1.list是可以在常數范圍內在任意位置進行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。

? 2.list的底層是雙向鏈表結構,帶有哨兵位的頭結點 。

? 3. listforward_list非常相似:最主要的不同在于forward_list是單鏈表,只能朝前迭代,已讓其更簡單高效。

? 4.由于底層是鏈表結構,list通常在任意位置進行插入,刪除元素的執行效率更好。

? 5. 與其他序列式容器相比,listforward_list最大的缺陷是不支持任意位置的隨機訪問,比如:要訪問list的第6個元素,必須從已知的位置(比如頭部或者尾部)迭代到該位置,在這段位置上迭代需要線性的時間開銷;list還需要一些額外的空間,以保存每個節點的相關聯信息(對于存儲類型較小元素的大list來說這 可能是一個重要的因素)

? 6.在list這個容器里面,是不支持[]等操作的。

list的底層:(雙向帶頭循環鏈表)

二.list的使用:

1.list的構造:

(1)empty container constructor (default constructor):構造空的list。

list<int> mylist;

(2)?fill constructor:構造一個有n個元素的鏈表,每個元素的值都是val。

list<int> list4(10, 1);
for (auto e : list4) {cout << e << " ";
}
//如上代碼就成功構造了一個有10個1的鏈表

(3)?range constructor:使其元素數量與區間 [first,last) 內的元素數量相同,并且每個元素都是根據該區間內對應位置的元素原位構造(emplace-constructed)而成,保持相同的順序。

vector<int> t1 = { 1,2,3,4,5,6,7,8,9 };
int a[] = { 1,2,3,4 };
list<int> list2(t1.begin(), t1.end());
list<int> list3(a, a + 4);
//值得關注的是,要求傳遞的是迭代器,但是也可以傳數組的指針

(4)copy constructor (and copying with allocator):拷貝構造。(同其他的容器一模一樣,不多介紹如何使用)

(5)暫時不介紹,后面再介紹。

(6)initializer list constructor:簡單點來說就是把想存進list的值全部用一個花括號括起來,每個值用逗號分隔開,然后用這些值構造一個list。

list<int> list1 = { 1,2,3,4,5,6,7,8,9 };

2.capacity:

其中max_size其實用的不多,這點在vector里面也一樣,上面兩個和其他容器的用法一模一樣。

3.element access:

這兩個函數返回的分別是鏈表的第一個元素和最后一個元素。

4.Modifiers:

?(挑一些特殊和重要的講不講的和其他容器使用差不多)

(1)assign:在 C++ 標準庫中,std::list?的?assign()?方法用于替換鏈表中的所有元素,支持多種賦值方式。它會清空原鏈表,再將新元素賦值給鏈表。

list<int> numbers;
numbers.assign(3, 100);
 std::vector<int> src = {1, 2, 3, 4};std::list<int> numbers;numbers.assign(src.begin(), src.end()); // 鏈表變為 {1, 2, 3, 4}
 std::list<char> chars;chars.assign({'a', 'b', 'c'}); // 鏈表變為 {'a', 'b', 'c'}

(2)emplace_front:在鏈表的首部直接構造一個新元素,跟push_front的功能差不多,但是二者的效率可能會有一些不同。

(3)insert:提供了很多不同的版本:

分別舉例:


int main ()
{std::list<int> mylist;std::list<int>::iterator it;// set some initial values:for (int i=1; i<=5; ++i) mylist.push_back(i); // 1 2 3 4 5it = mylist.begin();++it;       // it points now to number 2           ^mylist.insert (it,10);                        // 1 10 2 3 4 5//在pos位置insert一個val// "it" still points to number 2                      ^mylist.insert (it,2,20);                      // 1 10 20 20 2 3 4 5//在pos位置insert指定數目的val--it;       // it points now to the second 20            ^std::vector<int> myvector (2,30);mylist.insert (it,myvector.begin(),myvector.end());// 1 10 20 30 30 20 2 3 4 5//在pos位置inset一段迭代器區間所對應的值std::cout << "mylist contains:";for (it=mylist.begin(); it!=mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

list里面的list由于不會擴容,所以沒有迭代器失效的問題,但是返回值也是迭代器。

(4)erase:

erase提供了兩種方式,在pos位置刪除和刪除一段迭代器區間。如同vector一樣,erase有迭代器失效的效果,所以返回的是pos位置的下一個迭代器位置。

(5)swap:交換兩個鏈表的內容:

int main() {std::list<int> a = {1, 2, 3};std::list<int> b = {4, 5};a.swap(b); // 交換 a 和 b 的內容std::cout << "a: ";for (int x : a) std::cout << x << " "; // 輸出: 4 5std::cout << "\nb: ";for (int x : b) std::cout << x << " "; // 輸出: 1 2 3
}

5.operations:

(1)splice:

?std::list?的?splice()?方法用于將一個鏈表的元素轉移到另一個鏈表中,且不會導致元素的復制或移動,而是直接修改鏈表的內部指針,因此效率極高(時間復雜度為 O (1))。這個函數用到的地方不是很多,但是后面會有大用處。將一個鏈表的元素轉移到另一個鏈表中,另一個鏈表也可以是自己本身。

(2)remove:

??std::list?的?remove()?方法用于刪除鏈表中所有等于特定值的元素。它會遍歷整個鏈表,移除所有匹配的元素,并自動調整鏈表結構,保持元素間的連續性。需要傳遞的參數就是要刪除的值val

? remove_if就是和上面的作用差不多,但是需要滿足一定的條件。

(3)unique:

std::list?的?unique()?方法用于移除鏈表中相鄰的重復元素,只保留其中一個。它會遍歷鏈表,將相鄰且值相等的元素壓縮為單個元素,從而使鏈表中的元素唯一(僅針對相鄰元素)。

(4)merge:

std::list?的?merge()?方法用于將另一個有序鏈表合并到當前鏈表中,合并后當前鏈表仍保持有序。使用這個函數的前提是,兩個鏈表必須已經按相同順序排序

int main() {std::list<int> a = {1, 3, 5};std::list<int> b = {2, 4, 6};// 將 b 合并到 a 中,a 仍保持有序a.merge(b);// 輸出: 1 2 3 4 5 6for (int num : a) {std::cout << num << " ";}// b 變為空鏈表std::cout << "\nb size: " << b.size(); // 輸出: 0
}

合并之后被合并的那個鏈表會變成空的鏈表。

(5)sort:

由于迭代器類型的原因,sort不能使用<algorithm>頭文件里面的sort,所以單獨寫了一個sort,但是在list里面的這個sort是歸并排序,在進行大量數據排序的時候效率并沒有算法庫里面的sort效率高,因此使用的時候經常將list里面的元素放到vector里面,如何排好序后再assign回list里面。

原因在下面解釋。

(6)reverse:

不能使用算法庫里面的reverse的原因和sort一樣。

三.迭代器類型:

?迭代器有很多種,是根據容器的底層來決定的。inputiterator(輸入迭代器),forwarditerator(前向迭代器),bidirectioniterator(雙向迭代器),randmaccessiterator(隨機訪問迭代器)。

?inputiterator迭代器和forwarditerator都是只支持++,*的操作,雙向迭代器支持++,--,*的操作,隨機迭代器支持不僅支持前面所有的,還支持額外的隨機訪問,比如+n,> , <, 迭代器之間的減法等操作。

一個容器是否能使用算法庫里面的函數,需要看迭代器類型,在前面列舉的類型里面,按順序是包含關系。這是按照迭代器的功能來劃分的。

那么為什么list容器不能調用sort函數呢,list容器是雙向迭代器,而sort要求的是隨機迭代器,所以不能調用,反之,如果有一個隨機迭代器的容器,那么它是可以取使用要求是雙向迭代器的函數的。

四.補充一些知識:

---->? ?計算機的存儲體系如圖所示:

? ? ? ? ? ? ??

? ? ?->平時最關注的就是主存以及本地磁盤。

? ? ?->其中主存是帶電的,存儲速度很快,沒有電就不能存儲數據,一旦斷電,RAM (主存一般指ram,然后ram又分為dram和sram)中存儲的數據就會立即丟失,這就是為什么主存是易失性存儲器。而本地磁盤是不帶電的,沒有電它也可以存儲數據,在斷電后仍能保存數據,屬于非易失性存儲器。

? ? ->我們書寫一個順序表或者鏈表,它都是存放在主存(也就是通常說的內存)里面的,數據結構就是在內存中對數據進行管理,所以當然是在主存上的。我們對順序表,鏈表的數據進行遍歷和修改的時候,是cpu來完成的,但是cpu是不能直接訪問內存的,形象一點說,這是因為它太“快”了,而它覺得內存太慢了。這時候就有一個cpu高速緩存的概念了:? ? ??

cpu的機制是這樣的,比如說我要訪問一個指針,cpu先進緩存,如果這個指針在緩存里面,那么就叫做“命中”,這樣cpu就可以直接訪問了。如果“不命中”的情況下,內存的數據(當然不可能是內存的全部數據)會先進入緩存里面,然后再讓cpu去“命中”。在這樣的條件下就有一個緩存命中率的概念產生,對于順序表和鏈表先說結論就是順序表的緩存命中率高,而鏈表的緩存命中率低。內存在把數據給緩存的時候,假設要用的數據是4個字節,它就會從內存里面多拿連續的一部分給緩存(這是局部性原理預取相鄰的數據的效果,但是具體多取多少,這是又是硬件等多方面因素決定的)。稍微應用一下豆包的話來類比一下這個局部性原理:

由于順序表的結構優勢,使得在上述原理下“命中率”變高,雖然在鏈表的一個節點的后面會多拿一些數據,但是包含下一個節點的概率不大,所以鏈表的“命中率低”。

--------取自《深度理解計算機系統》--------。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/88377.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/88377.shtml
英文地址,請注明出處:http://en.pswp.cn/web/88377.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ntfs!LfsUpdateLfcbFromRestart函數分析之Ntfs!LfsFindOldestClientLsn

第0部分&#xff1a;//// Find the oldest client Lsn. Use the last flushed Lsn as a starting point.//Lfcb->OldestLsn Lfcb->LastFlushedLsn;LfsFindOldestClientLsn( RestartArea,Add2Ptr( RestartArea, Lfcb->ClientArrayOffset, PLFS_CLIENT_RECORD ),&…

「日拱一碼」021 機器學習——特征工程

目錄 特征選擇 過濾法&#xff08;Filter Methods&#xff09; 方差選擇法 相關系數法 卡方檢驗 包裹法&#xff08;Wrapper Methods&#xff09; 遞歸特征消除&#xff08;RFE&#xff09; 嵌入法&#xff08;Embedded Methods&#xff09; L1正則化&#xff08;Lasso…

k8s:安裝 Helm 私有倉庫ChartMuseum、helm-push插件并上傳、安裝Zookeeper

ChartMuseum 是 Kubernetes 生態中用于存儲、管理和發布 Helm Charts 的開源系統&#xff0c;主要用于擴展 Helm 包管理器的功能 核心功能 ?集中存儲?&#xff1a;提供中央化倉庫存儲Charts&#xff0c;支持版本管理和權限控制。 ? ?跨集群部署?&#xff1a;支持多集群環境…

C++編程學習(第二天)

1、求a和b兩個數之和。#include <iostream> using namespace std;int main() {int a, b, sum; //定義變量a、b、sumcout << "請輸入第一個數字a: "; //打印需要顯示的字符串cin >> a; // >&…

毫米波雷達守護銀發安全:七彩喜跌倒檢測儀重構居家養老防線

在老齡化加速與獨居老人數量攀升的背景下&#xff0c;跌倒已成為威脅老年人生命安全的“隱形殺手”。七彩喜跌倒檢測儀以毫米波雷達技術為核心&#xff0c;通過“非接觸式監測智能預警”重塑居家安全防護體系&#xff0c;為銀發群體構建起全天候、無感化的數字守護網。技術突破…

面試復盤:節流中第二次觸發的事件?答錯補課

面試復盤&#xff1a;節流中第二次觸發的事件&#xff1f;答錯補課 背景描述 今天面試時被問到一個看似基礎但暗藏玄機的問題&#xff1a;“節流&#xff08;Throttle&#xff09;函數中&#xff0c;第二次觸發的那一幀事件是否會被丟掉&#xff1f;” 我基于對經典節流實現的…

Spark偽分布式集群搭建(Ubuntu系統)

環境準備 系統要求&#xff1a;Ubuntu 20.04/22.04 LTS 軟件版本&#xff1a; Hadoop 3.3.5 JDK 8 Spark-3.5.6-bin-hadoop3 硬件要求&#xff1a;至少4GB內存&#xff0c;20GB磁盤空間 以下是基于Ubuntu系統的Spark偽分布式集群搭建全流程。以Spark 3.5.6 Hadoop 3.3.…

【快手】數據挖掘面試題0001:查找連續三天登錄的用戶

文章大綱一、測試數據構建二、自連接方案三、窗口函數方案一張用戶表&#xff0c;uer_id&#xff0c;signin_date&#xff0c;大概是這么幾項&#xff0c;查找連續三天登錄的用戶。 比如說&#xff0c;1,2兩天登錄不是連續三天&#xff0c;456登錄為連續三天登錄&#xff0c;56…

簡說scp命令

簡單介紹 scp的全稱是&#xff1a;Secure Copy Protocol&#xff08;安全復制協議&#xff09;&#xff0c;是Linux中用于在網絡中安全傳輸文件的命令行工具。它基于SSH協議&#xff0c;用于在本地服務器和遠程服務器之間&#xff0c;或者兩臺遠程服務器之間復制文件或目錄。 s…

自動化測試解決方案Parasoft SOAtest無腳本UI測試實踐指南

傳統UI自動化測試常面臨技術門檻高、維護成本大、穩定性差等挑戰。尤其在頁面頻繁變更時&#xff0c;測試腳本的更新和維護會顯著降低測試效率。 自動化測試解決方案Parasoft SOAtest通過可視化操作和智能元素定位技術&#xff0c;無需編寫代碼&#xff0c;讓測試人員能夠像真…

vscode配置頭文件和編譯器

在 VS Code 中配置編譯器和頭文件路徑需要修改兩個核心文件&#xff1a;c_cpp_properties.json&#xff08;用于智能提示&#xff09;和 tasks.json&#xff08;用于構建&#xff09;。以下是詳細步驟&#xff1a; —### 1. 配置智能提示和頭文件路徑 (c_cpp_properties.json)作…

HTML+JS+CSS制作一個數獨游戲

閑來無事&#xff0c;用HTMLJSCSS制作了一個數獨游戲消遣。其實主要是自己做題的時候用筆畫刪除數字太容易出錯&#xff0c;所以想搞一個程序稍微輔助一下。通過制作這個程序&#xff0c;反而提高了手工做題的水平&#xff0c;至少學會了記錄步數以便于回退。 20250710功能更新…

嵌入式硬件中電容的基本原理與實現詳解02

我們今天重點討論點知識點如下: 1.各種種類的電容優缺點對比講解 2.電容的標稱值介紹 3.電容的單位介紹 4.常見的電壓信號有哪些? 5. 電容的耐壓值講解 6.電容的容值有哪些? 7.12pF、15pF 電容常用在什么場合? 8. 振蕩電路中使用的電容常常需要使用什么材質的電容? 9.100n…

Python訓練打卡DAY46

DAY46&#xff1a;通道注意力&#xff08;SE注意力&#xff09; 恩師浙大疏錦行 知識點&#xff1a; 不同CNN層的特征圖&#xff1a;不同通道的特征圖什么是注意力&#xff1a;注意力家族&#xff0c;類似于動物園&#xff0c;都是不同的模塊&#xff0c;好不好試了才知道。通…

fastadmin_php專項

1.時間的判斷,還有就是在php這邊如何去拿前端html元素上面的值input($row.borrowtime);// 創建兩個 DateTime 對象$row_expecttime new \DateTime(input($row.borrowtime));$par_expecttime new \DateTime( $params[expecttime]); // // 計算兩個日期之間的差異 // …

如何在MySQL中選擇使用InnoDB還是MyISAM引擎?

在 MySQL 中選擇 InnoDB 還是 MyISAM 存儲引擎時&#xff0c;需根據應用場景的需求權衡功能、性能和數據完整性。以下是具體的選擇指南&#xff1a; 1. 優先考慮事務和外鍵需求必須使用 InnoDB&#xff1a; 若應用需要 事務支持&#xff08;如金融轉賬、訂單處理&#xff09;或…

邀請函 | 知從科技邀您共赴2025 RISC-V 中國峰會

第五屆RISC-V中國峰會將于2025年7月16至19日在上海張江科學會堂隆重舉辦&#xff0c;本屆峰會由上海開放處理器產業創新中心&#xff08;SOPIC&#xff09;主辦&#xff0c;RISC-V國際開源實驗室&#xff08;RIOS實驗室&#xff09;和上海張江高科技園區開發股份有限公司聯合主…

企業數字化轉型規劃和建設方案(管理架構、應用架構、技術架構)PPT

一、戰略定位與核心目標以 “技術賦能業務&#xff0c;數據驅動創新” 為核心思路&#xff0c;構建 “三步走” 戰略演進路徑&#xff0c;實現 IT 從 “基礎支撐” 到 “戰略引擎” 的升級&#xff1a;IT1.0&#xff08;1-2 年&#xff09;&#xff1a;夯實基礎能力定位 “穩健…

基于Uniapp+MySQL+PHP的景區多商戶小程序源碼系統 帶完整的搭建指南

溫馨提示&#xff1a;文末有資源獲取方式該系統采用 PHP MySQL 的經典開發組合。PHP 作為一種廣泛使用的開源腳本語言&#xff0c;具有簡單易學、運行速度快、跨平臺性強等優點&#xff0c;能夠快速開發出功能強大的 Web 應用程序。MySQL 則是一款穩定可靠的關系型數據庫管理系…

阿里云和騰訊云RocketMQ 發消息和消費消息客戶端JAVA接口

一、RocketMQ 概述RocketMQ 是阿里巴巴開源的一款分布式消息中間件&#xff0c;后捐贈給 Apache 基金會成為頂級項目。它具有低延遲、高并發、高可用、高可靠等特點&#xff0c;廣泛應用于訂單交易、消息推送、流計算、日志收集等場景。核心特點分布式架構&#xff1a;支持集群…