《STL--list的使用及其底層實現》

引言:

上次我們學習了容器vector的使用及其底層實現,今天我們再來學習一個容器list
這里的list可以參考我們之前實現的單鏈表,但是這里的list雙向循環帶頭鏈表,下面我們就開始list的學習了。

一:list的介紹

list的介紹文檔:

二:list的使用

1. 約定:

關于list的接口眾多,下面我們只介紹一些比較常用的接口,其他接口同學們可以自行去list的介紹文檔中學習。

2. list的構造:

  1. list (size_type n, const value_type& val =value_type()):構造的list中包含n個值為val的元素。
  2. list():構造空的list
  3. list (const list& x):拷貝構造函數。
  4. list (InputIterator first, InputIterator last):[first, last)區間中的元素構造
    list
代碼演示:

在這里插入圖片描述

3.list iterator的使用

注:這里大家先將list的迭代器理解為指向節點的一個指針。

  1. begin:返回第一個元素的迭代器。
  2. end:返回最后一個元素下一個位置的迭代器。
  3. rbegin:返回第一個元素的reverse_iterator,即end位置。
  4. rend:返回最后一個元素下一個位置的reverse_iterator,即begin位置。
代碼演示:

在這里插入圖片描述
注:

  1. beginend為正向迭代器,對迭代器執行++操作,迭代器向后移動
  2. rbegin(end)rend(begin)為反向迭代器,對迭代器執行++操作,迭代器向前移動

4.list capacity的使用

  1. empty:檢測list是否為空,為空返回true,反之則返回false
  2. size:計算list中有效數據的個數。
代碼演示:

在這里插入圖片描述

5. list element access

  1. front:返回list的第一個節點中值的引用。
  2. back:返回list的最后一個節點中值的引用。
代碼演示:

在這里插入圖片描述

6. list modifiers

  1. push_front:list首元素前插入值為val的元素。
  2. pop_front:刪除list中第一個元素。
  3. push_back:list尾部插入值為val的元素。
  4. pop_back:刪除list中最后一個元素。
  5. insert:list position 位置中插入值為val的元素。
  6. erase:刪除list position位置的元素。
  7. swap:交換兩個list中的元素。
  8. clear:清空list中的有效元素。
代碼演示:
(1)push_back(front) pop_back(front)

在這里插入圖片描述

(2)eraseinsert

在這里插入圖片描述
在這里插入圖片描述

swapclear

在這里插入圖片描述
在這里插入圖片描述

7. list迭代器失效問題

前面說過,此處大家可將迭代器暫時理解成類似于指針,迭代器失效即迭代器所指向的節點的無效,即該節點被刪除了。因為list的底層結構為帶頭結點的雙向循環鏈表,因此在list中進行插入時是不會導致list的迭代器失效的,只有在刪除時才會失效,并且失效的只是指向被刪除節點的迭代器,其他迭代器不會受到影響。

在這里插入圖片描述

這里想要解決迭代器失效的話,處理方式和之前是一樣的,需要對其重新進行賦值:

在這里插入圖片描述

三:list的模擬實現

1. 思考:

這里在模擬實現list時就和vector的實現有所區別了,之前實現的vector的本質上一個數組,其迭代器和原生指針沒什么區別,對其迭代器解引用就可以拿到對應的數據,但是這里的list里面存儲的是一個個節點,因此這里的迭代器并不是單純的原生指針,你對節點指針解引用的話拿到的是一個節點,并不能直接拿到節點里的數據,但是這不是我們期望的,按照我們的邏輯是解引用節點指針是要拿到這個節點指針對應節點里面的數據,因此這里在模擬實現的時候就比之前要復雜一點,牽扯到迭代器的構造以及有關迭代器的一些重載。

2.基本框架:

(1)節點結構:

在這里插入圖片描述

(2)迭代器結構:

在這里插入圖片描述

(3)鏈表結構:

在這里插入圖片描述

3. 迭代器結構完善

(1)* 重載:

在這里插入圖片描述

(2) 前置++和后置++重載:

在這里插入圖片描述

(3) 前置- - 和后置 - - 重載:

在這里插入圖片描述

(4) 比較運算符重載:

在這里插入圖片描述

4. 構造函數

在這里插入圖片描述
注:這里在構造的過程中由于會對e進行解引用,因此這里要用引用。

5. beginend

在這里插入圖片描述

6. insert 函數

在這里插入圖片描述
注:由于這里除了數據的申請,其他的邏輯和之前實現的雙向鏈表沒啥區別,就不細講了。

7. push_back 函數

在這里插入圖片描述
注:這里就直接復用insert即可。

8. push_front 函數

在這里插入圖片描述

9. erase 函數

在這里插入圖片描述
注:

  1. 這里需要注意頭結點我們是不能動的。(大哥動不得
  2. 為解決erase引起的迭代器失效問題,這里我們的erase給了返回值。

10. pop_back 函數

在這里插入圖片描述
注:這里就是直接復用erase即可。

11. pop_front 函數

在這里插入圖片描述

12. clear 函數

在這里插入圖片描述

13. 析構函數

在這里插入圖片描述

14. size 函數

注:為了避免重復遍歷鏈表來計算個數,因此這里我們就來維護一個成員變量_size,因此之前的插入和刪除都需要維護_size
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

15. swap 函數

在這里插入圖片描述

四: 拷貝構造函數引起的問題及解決方案

1. 問題的引發

我們這里在實現拷貝構造函數的時候出現了以下問題:
在這里插入圖片描述
那么為什么會出現這個問題呢?

2. 思考:

因為拷貝構造函數這里給的參數是const類類型,但是這里在構造的過程中用到了范圍for,我們知道,范圍for本質上就是迭代器的替換,并且因為需要進行解引用,所以這里的范圍for我們用的是引用,但是由于傳入參數是const類型,這里需要const類型的迭代器來支持,所以這里才會出現問題,因此我們就需要實現const類型的迭代器。

3. 解決方案:

這里由于const迭代器和普通類型的迭代器就一點不同,如果再封裝一個類的話就太冗余了,因此這里就可以從模版下手:
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
這個時候就解決了上面出現的問題,而且這樣使得我們在使用不同的迭代器時編譯器能夠自動推導類型。

4. 賦值運算符重載:

在這里插入圖片描述

五:補充內容— -> 重載

1. 引入:

首先我們來看vector存儲自定義類型時的訪問:

在這里插入圖片描述
在這里插入圖片描述
下面再來看用list來存儲自定義類型時的訪問:

在這里插入圖片描述

可以看到用list來存儲自定義類型的時候就不能用->來訪問,這是為什么呢?
還是回到前面提到的迭代器的區別,vector的迭代器就可以理解為原生指針,用->就可以拿到其里面的數據,而list這里的迭代器->的話拿到的是節點,而不是數據,因此,這里這樣寫就有問題,那么我們看一下標準庫里面的list的->
在這里插入圖片描述

可以看到標準庫里面的list就可以通過->來訪問數據,這是因為標準庫里的list->進行了特殊處理,因此我們這里也需要對->進行重載才可以。

2. -> 重載:

在這里插入圖片描述
:這里->的重載看著就有點奇怪了,注意這里返回的是指向數據的指針(數據的地址)
在這里插入圖片描述
在這里插入圖片描述
注意這里的兩種寫法都可以,第一種方式只是編譯器對其進行了特殊處理,其實第二種寫法更符合我們理解的邏輯。

完結!!!

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

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

相關文章

docker中使用openresty

1.為什么要使用openresty 我這邊是因為要使用1Panel,第一個最大的原因,就是圖方便,比較可以一鍵安裝。但以前一直都是直接安裝nginx。所以需要一個過度。 2.如何查看openResty使用了nginx哪個版本 /usr/local/openresty/nginx/sbin/nginx …

vscode包含工程文件路徑

在 VSCode 中配置 includePath 以自動識別并包含上層目錄及其所有子文件夾,需結合通配符和相對/絕對路徑實現。以下是具體操作步驟及原理說明: 1. 使用通配符 ** 遞歸包含所有子目錄 在 c_cpp_properties.json 的 includePath 中,${workspac…

【排序算法】典型排序算法 Java實現

以下是典型的排序算法分類及對應的 Java 實現,包含時間復雜度、穩定性說明和核心代碼示例: 一、比較類排序(通過元素比較) 1. 交換排序 ① 冒泡排序 時間復雜度:O(n)(優化后最優O(n)) 穩定性&…

多模態大語言模型arxiv論文略讀(八十七)

MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文標題:MG-LLaVA: Towards Multi-Granularity Visual Instruction Tuning ?? 論文作者:Xiangyu Zhao, Xiangtai Li, Haodong Duan, Haian Huang, Yining Li, Kai Chen, Hua Ya…

塔能節能平板燈:點亮蘇州某零售工廠節能之路

在蘇州某零售工廠的運營成本中,照明能耗占據著一定比例。為降低成本、提升能源利用效率,該工廠與塔能科技攜手,引入塔能節能平板燈,開啟了精準節能之旅,并取得了令人矚目的成效。 一、工廠照明能耗困境 蘇州該零售工廠…

數據庫事務的四大特性(ACID)

一、前言 在現代數據庫系統中,事務(Transaction)是確保數據一致性和完整性的重要機制。事務的四大特性——原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)…

8 種快速易用的Python Matplotlib數據可視化方法

你是否曾經面對一堆復雜的數據,卻不知道如何讓它們變得直觀易懂?別慌,Python 的 Matplotlib 庫是你數據可視化的最佳伙伴!它簡單易用、功能強大,能將枯燥的數字變成引人入勝的圖表。無論是學生、數據分析師還是程序員&…

springboot 控制層調用業務邏輯層,注入報錯,無法自動裝配 解決辦法

報錯: 解決:愿意是業務邏輯層,即service層的具體實現類沒有加注解Service導致的,加上解決了!!

如何提高獨立服務器的安全性?

獨立服務器相對于其它服務器來說,整體的硬件設備都是獨立的同時還有著強大的服務器性能,其中CPU設備能夠決定著服務器的運算能力,所以獨立服務器的安全性受到企業格外的重視,嚴重的話會給企業造成巨大的資金損失。 那么&#xff0…

關于 Web 風險點原理與利用:6. 邏輯風險點

一、分類: 1.1 越權訪問 **越權訪問(Authorization Bypass)**是指:攻擊者繞過了權限控制機制,訪問或操作了非其權限范圍內的資源或功能。 換句話說,系統該攔你沒攔,你就越權成功了。 1.1.1 …

分布式緩存:ZSET → MGET 跨槽(cross‐slot)/ 并發 GET解決思路

文章目錄 緩存全景圖Pre問題描述解決思路一、管道(Pipelining)替代多線程二、使用 Hash Tag 保證數據同槽三、用 Hash 結構一次性批量取值四、把數據直接存進 ZSET(或用 RedisJSON) 小結 緩存全景圖 Pre 分布式緩存:緩…

開發AR導航助手:ARKit+Unity+Mapbox全流程實戰教程

引言 在增強現實技術飛速發展的今天,AR導航應用正逐步改變人們的出行方式。本文將手把手教你使用UnityARKitMapbox開發跨平臺AR導航助手,實現從虛擬路徑疊加到空間感知的完整技術閉環。通過本教程,你將掌握: AR空間映射與場景理…

助力 FPGA 國產化,ALINX 攜多款方案亮相深圳、廣州“紫光同創 FPGA 技術研討會”

5 月中旬,一年一度的紫光同創技術研討會系列活動正式拉開帷幕,相繼在深圳、廣州帶來 FPGA 技術交流盛宴。 ALINX 作為紫光同創官方合作伙伴,長期助力推動 FPGA 國產化應用發展,此次攜多款基于 Kosmo-2 系列產品開發的方案 demo 亮…

LeetCode 1040.移動石子直到連續II

在 X 軸上有一些不同位置的石子。給定一個整數數組 stones 表示石子的位置。 如果一個石子在最小或最大的位置,稱其為 端點石子。每個回合,你可以將一顆 端點石子 拿起并移動到一個未占用的位置,使得該石子不再是一顆 端點石子。 值得注意的…

梯度優化提示詞:精準引導AI分類

基于梯度優化的提示詞工程方法,通過迭代調整提示詞的嵌入向量,使其能夠更有效地引導模型做出正確分類。 數據形式 訓練數據 train_data 是一個列表,每個元素是一個字典,包含兩個鍵: text: 需要分類的文本描述label: 對應的標簽(“沖動"或"理性”)示例數據: …

JavaWeb:SpringBoot配置優先級詳解

3種配置 打包插件 命令行 優先級 SpringBoot的配置優先級決定了不同配置源之間的覆蓋關系,遵循高優先級配置覆蓋低優先級的原則。以下是詳細的優先級排序及配置方法說明: 一、配置優先級從高到低排序 1.命令行參數 優先級最高,通過keyvalu…

使用CentOS部署本地DeekSeek

一、查看服務器的操作系統版本 cat /etc/centos-release二、下載并安裝ollama 1、ollama下載地址: Releases ollama/ollama GitHubGet up and running with Llama 3.3, DeepSeek-R1, Phi-4, Gemma 3, Mistral Small 3.1 and other large language models. - Re…

Matplotlib 后端與事件循環

前言:很多時候,matplot跑出來的是這種靜態非交互的,如果想要可以交互,就得設定一個后端,例如 matplotlib.use(TkAgg)Matplotlib 后端 (Backend) Matplotlib 的設計理念是能夠以多種方式輸出圖形,無論是顯…

【JAVA】中文我該怎么排序?

📘 Java 中文排序教學文檔(基于 Collator) 🧠 目錄 概述Java 中字符串排序的默認行為為什么需要 Collator使用 Collator 進行中文排序升序 vs 降序排序自定義對象字段排序多字段排序示例總結對比表附錄:完整代碼示例 …

k8s-NetworkPolicy

在 Kubernetes 中,NetworkPolicy 是一種資源對象,用于定義 Pod 之間的網絡通信策略。它允許你控制哪些 Pod 可以相互通信,以及如何通信。通過使用 NetworkPolicy,可以實現更細粒度的網絡訪問控制,增強集群的安全性。 1…