(C++)STL:list認識與使用全解析

本篇基于https://cplusplus.com/reference/list/list/講解

認識

list是一個帶頭結點的雙向循環鏈表
在這里插入圖片描述
翻譯總結:

  1. 序列容器:list是一種序列容器,允許在序列的任何位置進行常數時間的插入和刪除操作。
  2. 雙向迭代:list支持雙向迭代,即可以向前和向后遍歷元素。
  3. 雙鏈表實現:list容器內部通過雙鏈表實現。每個元素都包含指向前一個元素和后一個元素的鏈接。
  4. 非連續存儲:與數組或vector不同,list中的元素可以存儲在不同的、不連續的內存位置。
  5. 內存開銷:由于需要額外的內存來存儲每個元素的鏈接信息,list相對于數組或vector會消耗更多的內存。
  6. 與forward_list的區別:list與forward_list相似,但forward_list是單鏈表,只能單向迭代,而list是雙鏈表,可以雙向迭代。
  7. 插入和刪除性能:與其他標準序列容器(如array、vector和deque)相比,list在已知迭代器位置的容器內插入、提取和移動元素時表現更好,尤其是在需要頻繁修改序列內容的情況下。
  8. 訪問性能:與array、vector和deque相比,list的主要缺點是缺乏通過位置直接訪問元素的能力。訪問特定位置的元素需要從已知位置(如序列的開始或結束)開始迭代,這需要線性時間。
  9. 適用場景:list適用于需要頻繁在序列中間插入和刪除元素的場景,以及需要雙向迭代的場景。對于需要頻繁訪問特定位置元素的場景,list可能不是最佳選擇。

接口

在string、vector的基礎上不作過多說明,僅強調差異的內容

遍歷

由于底層不是數組,由其訪問性能得知( 訪問性能:與array、vector和deque相比,list的主要缺點是缺乏通過位置直接訪問元素的能力。訪問特定位置的元素需要從已知位置(如序列的開始或結束)開始迭代,這需要線性時間。)
不再支持operator[],只支持迭代器遍歷和范圍for。

// list::begin
#include <iostream>
#include <list>int main ()
{int myints[] = {75,23,65,42,13};std::list<int> mylist (myints,myints+5);std::cout << "mylist contains:";for (std::list<int>::iterator it=mylist.begin(); it != mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

支持頭刪、頭插

在這里插入圖片描述

string、vector這兩個底層是數組的結構進行頭刪會導致大量的數據挪動,所以盡量避免頭插頭刪,只在必要時使用insert實現,但對于list,不會產生大量挪動消耗,因此有單獨的頭插頭刪函數。

容量操作

在這里插入圖片描述
沒有reserve,因為list是一個一個結點開辟、一個一個結點刪除的

額外增加的鏈表相關接口

在這里插入圖片描述

remove 刪除特定的值

注意其與erase的區別
在這里插入圖片描述

// remove from list
#include <iostream>
#include <list>int main ()
{int myints[]= {17,89,7,14};std::list<int> mylist (myints,myints+4);mylist.remove(89);std::cout << "mylist contains:";for (std::list<int>::iterator it=mylist.begin(); it!=mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在這里插入圖片描述

remove_if 條件刪除

merge 歸并

兩個有序list合并以后仍然有序
在這里插入圖片描述

(1)void merge(list<T>& x);
(2)使用自定義比較函數:void merge(list<T>& x, Compare comp);
這里,x 是要合并到當前列表的另一個列表,comp 是一個自定義的比較函數,它接受兩個參數并返回一個布爾值,指示第一個參數是否應該在第二個參數之前。

#include <iostream>
#include <list>// 自定義的比較函數
bool mycomparison (double first, double second)
{ return ( int(first)<int(second) ); }int main ()
{std::list<double> first, second;first.push_back (3.1);first.push_back (2.2);first.push_back (2.9);second.push_back (3.7);second.push_back (7.1);second.push_back (1.4);//先讓兩個列表是有序的first.sort();second.sort();
//(1)first.merge(second);// (second is now empty)合并后second變為空second.push_back (2.1);
//(2)first.merge(second,mycomparison);std::cout << "first contains:";for (std::list<double>::iterator it=first.begin(); it!=first.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在這里插入圖片描述

unique 去重

前提是有序的list!!原因和去重函數的底層實現有關

// list::unique
#include <iostream>
#include <cmath>
#include <list>// a binary predicate implemented as a function:
bool same_integral_part (double first, double second)
{ return ( int(first)==int(second) ); }// a binary predicate implemented as a class:
struct is_near {bool operator() (double first, double second){ return (fabs(first-second)<5.0); }
};int main ()
{double mydoubles[]={ 12.15,  2.72, 73.0,  12.77,  3.14,12.77, 73.35, 72.25, 15.3,  72.25 };std::list<double> mylist (mydoubles,mydoubles+10);mylist.sort();             //  2.72,  3.14, 12.15, 12.77, 12.77,// 15.3,  72.25, 72.25, 73.0,  73.35mylist.unique();           //  2.72,  3.14, 12.15, 12.77// 15.3,  72.25, 73.0,  73.35mylist.unique (same_integral_part);  //  2.72,  3.14, 12.15// 15.3,  72.25, 73.0mylist.unique (is_near());           //  2.72, 12.15, 72.25std::cout << "mylist contains:";for (std::list<double>::iterator it=mylist.begin(); it!=mylist.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在這里插入圖片描述

sort

默認排升序

  • 為什么標準庫里有sort,且vector都沒有單獨實現sort,list卻要單獨實現?

在這里插入圖片描述

  1. 迭代器按功能分類為單向、雙向、隨機迭代器,分類由容器的底層結構決定,底層連續存儲的,更好支持加減
  2. 三種迭代器有兼容關系:要求單向,可以用雙向和隨機,要求雙向,可以用隨機。
    包含大小:隨機>雙向>單向
  3. 算法的迭代器類型參數名字,暗示了其需要的迭代器類型要求
    std::sort需要隨機迭代器,而list的迭代器是雙向迭代器,所以list無法使用標準庫的sort
    reverse需要雙向迭代器,find需要只讀迭代器InputIterator(實際上代表單向、雙向、隨機迭代器都可以)

在這里插入圖片描述

  • 這個成員函數sort效率如何?
    效率遠不如std::sort。所以數據多的時候盡量不要使用這個sort
    當數據量為1000000時,拷貝到vector去排序再拷貝回來,vector的性能都好很多。
    在這里插入圖片描述

reverse 反轉

在這里插入圖片描述

splice 粘貼

把一個鏈表中的數據轉移到另一個鏈表里去
在這里插入圖片描述
注意list迭代器要求是雙向迭代器,無法通過begin()+幾或-幾來控制位置

// splicing lists
#include <iostream>
#include <list>int main ()
{std::list<int> mylist1, mylist2;std::list<int>::iterator it;// set some initial values:for (int i=1; i<=4; ++i)mylist1.push_back(i);      // mylist1: 1 2 3 4for (int i=1; i<=3; ++i)mylist2.push_back(i*10);   // mylist2: 10 20 30it = mylist1.begin();++it;                         // points to 2mylist1.splice (it, mylist2); // mylist1: 1 10 20 30 2 3 4// mylist2 (empty)// "it" still points to 2 (the 5th element)mylist2.splice (mylist2.begin(),mylist1, it);// mylist1: 1 10 20 30 3 4// mylist2: 2// "it" is now invalid.it = mylist1.begin();std::advance(it,3);           // "it" points now to 30mylist1.splice ( mylist1.begin(), mylist1, it, mylist1.end());// mylist1: 30 3 4 1 10 20
//實現一個list中的元素調整————輸入該list的迭代器std::cout << "mylist1 contains:";for (it=mylist1.begin(); it!=mylist1.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';std::cout << "mylist2 contains:";for (it=mylist2.begin(); it!=mylist2.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

在這里插入圖片描述

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

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

相關文章

Bash函數詳解

目錄**1. 基礎函數****2. 參數處理函數****3. 文件操作函數****4. 日志與錯誤處理****5. 實用工具函數****6. 高級函數技巧****7. 常用函數庫示例****總結&#xff1a;Bash 函數核心要點**1. 基礎函數 1.1 定義與調用 可以自定義函數名稱&#xff0c;例如將greet改為yana。?…

Python爬蟲實戰:研究rows庫相關技術

1. 引言 在當今數字化時代,互聯網上存在著大量有價值的表格數據,這些數據以 HTML 表格、CSV、Excel 等多種格式存在。然而,由于數據源的多樣性和不規范性,表格結構往往存在復雜表頭、合并單元格、不規則數據行等問題,給數據的自動化處理帶來了巨大挑戰。 傳統的數據處理工…

通過同態加密實現可編程隱私和鏈上合規

1. 引言 2023年9月28日&#xff0c;a16z 的加密團隊發布了 Nakamoto Challenge&#xff0c;列出了區塊鏈中需要解決的最重要問題。尤其是其中的第四個問題格外引人注意&#xff1a;“合規的可編程隱私”&#xff0c;因為Zama團隊已經在這方面積極思考了一段時間。本文提出了使…

封裝---統一封裝處理頁面標題

一.采用工具來實現(setPageTitle.ts)多個頁面中用更統一的方式設置 document.title&#xff0c;可以封裝一個工具函數:在utils目錄下新建文件:setPageTitle.ts如果要在每個頁面設置相同的網站標志可以使用下面的appNameconst appName: string import.meta.env.VITE_APP_NAMEex…

JAVA學習筆記 首個HelloWorld程序-002

目錄 1 前言 2 開發首個程序 3 小結 1 前言 在所有的開發語言中&#xff0c;基本上首先程序就是輸出HelloWorld&#xff0c;這里也不例外。這個需要注意的是&#xff0c;程序的核心功能是數據輸出&#xff0c;是要有一個結果&#xff0c;可能沒有輸入&#xff0c;但是一定有…

智慧監所:科技賦能監獄管理新變革

1. 高清教育&#xff1a;告別模糊畫面&#xff0c;學習更清晰傳統電視的雪花屏終于成為歷史&#xff01;新系統采用高清傳輸&#xff0c;課件文字清晰可見&#xff0c;教學視頻細節分明。某監獄教育科王警官說&#xff1a;"現在播放法律課程&#xff0c;服刑人員能清楚看到…

專題:2025供應鏈數智化與效率提升報告|附100+份報告PDF、原數據表匯總下載

全文鏈接&#xff1a;https://tecdat.cn/?p42926 在全球產業鏈重構與數字技術革命的雙重驅動下&#xff0c;供應鏈正經歷從傳統經驗驅動向數據智能驅動的范式變革。從快消品產能區域化布局到垂類折扣企業的效率競賽&#xff0c;從人形機器人的成本優化到供應鏈金融對中小企業的…

uniapp+vue3+ts項目:實現小程序文件下載、預覽、進度監聽(含項目、案例、插件)

uniapp+vue3+ts項目:實現小程序文件下載、預覽、進度監聽(含項目、案例、插件) 支持封裝調用: 項目采用uniapp+vue3+ts +京東nutUI 開發nutUi文檔:loadingPage組件:https://uniapp-nutui.tech/components/exhibition/loadingpage.html案例效果圖: 略博主自留地:參考本地…

用Python和OpenCV從零搭建一個完整的雙目視覺系統(六 最終篇)

本系列文章旨在系統性地闡述如何利用 Python 與 OpenCV 庫&#xff0c;從零開始構建一個完整的雙目立體視覺系統。 本項目github地址&#xff1a;https://github.com/present-cjn/stereo-vision-python.git 1. 概述 歡迎來到本系列文章的最后一篇。在過去的幾篇文章中&#…

Android View 繪制流程 簡述 (無限遞歸+BitMap問題)

繪制流程 在 Android 的 View 系統中&#xff0c;draw(canvas) 和 dispatchDraw(canvas) 是繪制流程中的兩個關鍵方法&#xff1a; 1. draw(canvas) 方法的作用 draw(canvas) 是 View 類中的核心繪制方法&#xff0c;它的主要職責包括&#xff1a; 繪制背景 - 調用 drawBac…

算法學習筆記:18.拉斯維加斯算法 ——從原理到實戰,涵蓋 LeetCode 與考研 408 例題

在隨機化算法領域&#xff0c;拉斯維加斯&#xff08;Las Vegas&#xff09;算法以其獨特的設計思想占據重要地位。與蒙特卡洛&#xff08;Monte Carlo&#xff09;算法不同&#xff0c;拉斯維加斯算法總能給出正確的結果&#xff0c;但運行時間具有隨機性 —— 在最壞情況下可…

26-計組-指令執行過程

一、指令周期1. 定義與組成定義&#xff1a;CPU取出并執行一條指令所需的全部時間&#xff0c;稱為指令周期。子周期劃分&#xff1a;取指周期&#xff08;必選&#xff09;&#xff1a;從存儲器取指令到指令寄存器&#xff08;IR&#xff09;。間址周期&#xff08;可選&#…

【JMeter】數據驅動測試

文章目錄創建數據文件加載數據文件根據數據文件請求接口、傳遞參數拓展含義&#xff1a;根據數據的數量、內容&#xff0c;自動的決定用例的數據和內容。數據驅動測試用例。步驟&#xff1a; 創建數據文件加載數據文件根據數據文件請求接口、傳遞參數 創建數據文件 Jmeter支…

Springboot實現一個接口加密

首先來看效果這個主要是為了防止篡改請求的。 我們這里采用的是一個AOP的攔截&#xff0c;在有需要這樣的接口上添加了加密處理。 下面是一些功能防篡改HMAC-SHA256 參數簽名密鑰僅客戶端 & 服務器持有防重放秒級時間戳 有效窗口校驗默認允許 5 分鐘防竊聽AES/CBC/PKCS5Pa…

斯坦福 CS336 動手大語言模型 Assignment1 BPE Tokenizer TransformerLM

所有代碼更新至 https://github.com/WangYuHang-cmd/CS336/tree/main/assignment1-basics 作業文件結構: CS336/assignment1-basics/ ├── tests/ # 測試文件目錄 │ ├── adapters.py # 適配器測試 │ ├── conftest.py # pyt…

Spring Cloud Gateway 實戰指南

關鍵詞&#xff1a;微服務、API網關、Spring Cloud Gateway、路由轉發、限流熔斷 ? 文章摘要 隨著互聯網應用規模的不斷擴大&#xff0c;傳統的單體架構逐漸向微服務架構轉型。在微服務架構中&#xff0c;API 網關作為系統的入口點&#xff0c;承擔了諸如請求路由、負載均衡、…

PyTorch自動微分:從基礎到實戰

目錄 1. 自動微分是什么&#xff1f; 1.1 計算圖 1.2 requires_grad 屬性 2. 標量和向量的梯度計算 2.1 標量梯度 2.2 向量梯度 3. 梯度上下文控制 3.1 禁用梯度計算 3.2 累計梯度 4. 梯度下降實戰 4.1 求函數最小值 4.2 線性回歸參數求解 5. 總結 在深度學習中&a…

Spring AI 項目實戰(十六):Spring Boot + AI + 通義萬相圖像生成工具全棧項目實戰(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰(一):Spring AI 核心模塊入門2Spring AI 項目實戰(二):Spring Boot + AI + DeepSeek 深度實戰(附完整源碼)3Spring AI 項目實戰(三):Spring Boot + AI + DeepSeek 打造智能客服系統(附完整源碼)4

從零到一:企業如何組建安全團隊

在這個"黑客滿天飛&#xff0c;漏洞遍地跑"的時代&#xff0c;沒有安全團隊的企業就像裸奔的勇士——雖然很有勇氣&#xff0c;但結局往往很悲慘。 &#x1f4cb; 目錄 為什么要組建安全團隊安全團隊的核心職能團隊架構設計人員配置策略技術體系建設制度流程建立實施…

業務訪問控制-ACL與包過濾

業務訪問控制-ACL與包過濾 ACL的定義及應用場景ACL&#xff08;Access Control List&#xff0c;訪問控制列表&#xff09;是用來實現數據包識別功能的&#xff1b;ACL可以應用于諸多場景&#xff1a; 包過濾功能&#xff1a;對數據包進行放通或過濾操作。NAT&#xff08;Netwo…