Day 26 C++ list容器(鏈表)

文章目錄

  • list基本概念
      • 定義
      • 結構
      • 雙向迭代器
      • 優點
      • 缺點
      • List和vector區別
          • 存儲結構
          • 內存管理
          • 迭代器穩定性
          • 隨機訪問效率
  • list構造函數——創建list容器
      • 函數原型
      • 示例
  • list 賦值和交換
      • 函數原型
  • list 大小操作
      • 函數原型
      • 示例
  • list 插入和刪除
      • 函數原型
      • 示例
  • list 數據存取
      • 函數原型
      • 注意
      • 示例
  • list 反轉和排序
      • 函數原型
      • 示例
      • 高級排序——在排序規則上再進行一次邏輯規則制定

list基本概念

定義

鏈表(list)是一種物理存儲單元上非連續的存儲結構,可以將數據進行鏈式存儲,數據元素的邏輯順序是通過鏈表中的指針鏈接實現的。STL中的鏈表是一個雙向循環鏈表。

結構

鏈表的組成:鏈表由一系列結點組。

結點的組成:一個是存儲數據元素的數據域,另一個是存儲下一個結點地址的指針域
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-P6joB49u-1691658357899)(assets/clip_image002-1547608564071.jpg)]

雙向迭代器

由于鏈表的存儲方式并不是連續的內存空間,因此鏈表list中的迭代器只支持前移和后移,屬于雙向迭代器

優點

  • 采用動態存儲分配,不會造成內存浪費和溢出
  • 鏈表執行插入和刪除操作十分方便,修改指針即可,不需要移動大量元素

缺點

  • 鏈表靈活,但是空間(指針域) 和 時間(遍歷)額外耗費較

> 鏈表在每個節點都需要存儲額外的指針域,會消耗更多的內存空間。此外,由于鏈表是非連續存儲的,訪問特定位置的元素需要從頭或尾按順序遍歷鏈表,時間復雜度為O(n),相對于向量的常數時間訪問O(1),效率較低。

List和vector區別

存儲結構

list是一個雙向鏈表,每個節點包含一個值和前后指針;
而vector是一個動態數組,使用連續的內存塊來存儲元素。

內存管理

由于list使用動態內存分配,可以在任意位置高效地插入和刪除元素,但同時會產生額外的指針開銷;
而vector使用連續的內存塊,盡管插入和刪除操作需要移動元素,但內存訪問位置更加連續,可以提供更好的緩存性能。

迭代器穩定性

在list中,插入或刪除元素不會影響已存在的迭代器的有效性;
而在vector中,當插入或刪除元素時,可能會導致迭代器失效,需要重新獲取。

隨機訪問效率

由于vector使用連續的內存塊,可以通過索引隨機訪問元素,并具有較好的性能;
而list為了訪問指定位置的元素,需要從頭或從尾按順序遍歷鏈表,效率較低。

在插入和刪除頻繁的場景下,list可能更適合;
而在需要快速隨機訪問元素或者容器規模較大的情況下,vector可能更合適。

list構造函數——創建list容器

函數原型

  • list<T> lst; //list采用采用模板類實現,對象的默認構造形式:
  • list(beg,end); //構造函數將[beg, end)區間中的元素拷貝給本身。
  • list(n,elem); //構造函數將n個elem拷貝給本身。
  • list(const list &lst); //拷貝構造函數。
    list構造方式同其他幾個STL常用容器一致

示例

#include <list>
#include <iostream>
#include <list>int main() {// 示例1:使用默認構造函數創建空的liststd::list<int> myList1;// 示例2:使用迭代器構造函數將數組中的元素拷貝到list中int arr[] = {1, 2, 3, 4, 5};std::list<int> myList2(arr, arr + sizeof(arr) / sizeof(int));// 示例3:使用元素數量和元素值構造liststd::list<int> myList3(3, 10); // 包含三個值為10的元素// 示例4:使用拷貝構造函數創建一個副本std::list<int> myList4(myList3);// 輸出list中的元素std::cout << "myList1: ";for (const auto& element : myList1) {std::cout << element << " ";}std::cout << std::endl;std::cout << "myList2: ";for (const auto& element : myList2) {std::cout << element << " ";}std::cout << std::endl;std::cout << "myList3: ";for (const auto& element : myList3) {std::cout << element << " ";}std::cout << std::endl;std::cout << "myList4: ";for (const auto& element : myList4) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

輸出
myList1:
myList2: 1 2 3 4 5
myList3: 10 10 10
myList4: 10 10 10

list 賦值和交換

函數原型

  • assign(beg, end); //將[beg, end)區間中的數據拷貝賦值給本身。
  • assign(n, elem); //將n個elem拷貝賦值給本身。
  • list& operator=(const list &lst); //重載等號操作符
  • swap(lst); //將lst與本身的元素互換

示例:

#include <iostream>
#include <list>int main() {std::list<int> myList1 = {1, 2, 3};std::list<int> myList2 = {4, 5, 6};std::cout << "Before swap:" << std::endl;std::cout << "myList1: ";for (const auto& element : myList1) {std::cout << element << " ";}std::cout << std::endl;std::cout << "myList2: ";for (const auto& element : myList2) {std::cout << element << " ";}std::cout << std::endl;// 使用swap函數交換兩個list的元素myList1.swap(myList2);std::cout << "After swap:" << std::endl;std::cout << "myList1: ";for (const auto& element : myList1) {std::cout << element << " ";}std::cout << std::endl;std::cout << "myList2: ";for (const auto& element : myList2) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

輸出
Before swap:
myList1: 1 2 3
myList2: 4 5 6
After swap:
myList1: 4 5 6
myList2: 1 2 3

list 大小操作

函數原型

  • size(); //返回容器中元素的個數

  • empty(); //判斷容器是否為空

  • resize(num); //重新指定容器的長度為num,若容器變長,則以默認值0填充新位置。

    ? //如果容器變短,則末尾超出容器長度的元素被刪除。

  • resize(num, elem); //重新指定容器的長度為num,若容器變長,則以elem值填充新位置。

    //如果容器變短,則末尾超出容器長度的元素被刪除。

示例

#include <iostream>
#include <list>int main() {std::list<int> myList = {1, 2, 3, 4, 5};// 使用size函數獲取容器中元素的個數std::cout << "Size of myList: " << myList.size() << std::endl;// 使用empty函數判斷容器是否為空if (myList.empty()) {std::cout << "myList is empty." << std::endl;} else {std::cout << "myList is not empty." << std::endl;}// 使用resize函數改變容器的長度為7,默認填充0myList.resize(7);std::cout << "myList after resize to size 7 with default value:" << std::endl;for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;// 使用resize函數改變容器的長度為10,使用值9填充新位置myList.resize(10, 9);std::cout << "myList after resize to size 10 with value 9:" << std::endl;for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;// 使用resize函數將容器的長度改為3myList.resize(3);std::cout << "myList after resize to size 3:" << std::endl;for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

輸出
Size of myList: 5
myList is not empty.
myList after resize to size 7 with default value:
1 2 3 4 5 0 0
myList after resize to size 10 with value 9:
1 2 3 4 5 0 0 9 9 9
myList after resize to size 3:
1 2 3

在示例中,我們創建了一個list對象myList并初始化它的元素。
然后,我們使用size函數輸出容器的大小,使用empty函數判斷容器是否為空。
接著,我們使用resize函數將容器的大小分別改變為7、10和3。
當容器變大時,新位置會用默認值0或指定的值9進行填充;
當容器變小時,末尾超出容器長度的元素會被刪除。最終,我們打印出修改后的容器內容

list 插入和刪除

函數原型

  • push_back(elem);//在容器尾部加入一個元素
  • pop_back();//刪除容器中最后一個元素
  • push_front(elem);//在容器開頭插入一個元素
  • pop_front();//從容器開頭移除第一個元素
  • insert(pos,elem);//在pos位置插elem元素的拷貝,返回新數據的位置。
  • insert(pos,n,elem);//在pos位置插入n個elem數據,無返回值。
  • insert(pos,beg,end);//在pos位置插入[beg,end)區間的數據,無返回值。
  • clear();//移除容器的所有數據
  • erase(beg,end);//刪除[beg,end)區間的數據,返回下一個數據的位置。
  • erase(pos);//刪除pos位置的數據,返回下一個數據的位置。
  • remove(elem);//刪除容器中所有與elem值匹配的元素。

注意
插入多個數據無返回值刪除返回下一個數據位置
beg end 均為迭代器

示例

#include <iostream>
#include <list>int main() {std::list<int> myList = {1, 2, 3, 4, 5};std::cout << "Initial myList:" << std::endl;for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;// 在容器尾部加入一個元素myList.push_back(6);// 刪除容器中最后一個元素myList.pop_back();// 在容器開頭插入一個元素myList.push_front(0);// 從容器開頭移除第一個元素myList.pop_front();// 在指定位置插入元素的拷貝auto it = myList.begin();std::advance(it, 2);myList.insert(it, 7);// 在指定位置插入多個相同元素it = myList.begin();std::advance(it, 3);myList.insert(it, 3, 8);// 在指定位置插入另一個區間的元素std::list<int> newElements = {9, 10};it = myList.begin();std::advance(it, 4);myList.insert(it, newElements.begin(), newElements.end());std::cout << "myList after modifications:" << std::endl;for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;// 移除容器的所有數據myList.clear();std::cout << "myList after clear:" << std::endl;if (myList.empty()) {std::cout << "myList is empty." << std::endl;} else {std::cout << "myList is not empty." << std::endl;}return 0;
}

list 數據存取

函數原型

  • front(); //返回第一個元素。
  • back(); //返回最后一個元素。

?

注意

list容器的迭代器是雙向迭代器,不支持隨機訪問,沒有索引,不能跳躍訪問 ,也不可以通過[]或者at方式訪問數據

示例

#include <list>//數據存取
void test01()
{list<int>L1;L1.push_back(10);L1.push_back(20);L1.push_back(30);L1.push_back(40);//cout << L1.at(0) << endl;//錯誤 不支持at訪問數據//cout << L1[0] << endl; //錯誤  不支持[]方式訪問數據cout << "第一個元素為: " << L1.front() << endl;cout << "最后一個元素為: " << L1.back() << endl;//list容器的迭代器是雙向迭代器,不支持隨機訪問list<int>::iterator it = L1.begin();//it = it + 1;//錯誤,不可以跳躍訪問,即使是+1
}int main() {test01();system("pause");return 0;
}

list 反轉和排序

函數原型

  • reverse(); //反轉鏈表
  • sort(); //鏈表排序 //默認的排序規則 從小到大 升序

示例

#include <iostream>
#include <list>int main() {std::list<int> myList = {5, 2, 4, 1, 3};// 反轉鏈表myList.reverse();std::cout << "Reversed list: ";for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;// 鏈表排序myList.sort();std::cout << "Sorted list: ";for (const auto& element : myList) {std::cout << element << " ";}std::cout << std::endl;return 0;
}

輸出
Reversed list: 3 1 4 2 5
Sorted list: 1 2 3 4 5

高級排序——在排序規則上再進行一次邏輯規則制定

  • 對于自定義數據類型,必須要指定排序規則,否則編譯器不知道如何進行排序
  • 高級排序只是在排序規則上再進行一次邏輯規則制定,并不復雜
#include <iostream>
#include <vector>
#include <algorithm>struct Student {std::string name;int age;int score;
};bool compareStudents(const Student& student1, const Student& student2) {// 先按分數降序排序if (student1.score != student2.score) {return student1.score > student2.score;}// 如果分數相同,則按年齡升序排序if (student1.age != student2.age) {return student1.age < student2.age;}// 如果分數和年齡都相同,則按姓名的字典序升序排序return student1.name < student2.name;
}int main() {// 創建學生對象std::vector<Student> students = {{"Alice", 20, 90}, {"Bob", 18, 85}, {"Charlie", 19, 90}};// 使用自定義的排序規則對學生進行排序std::sort(students.begin(), students.end(), compareStudents);// 輸出排序結果for (const auto& student : students) {std::cout << "Name: " << student.name << ", Age: " << student.age << ", Score: " << student.score << std::endl;}return 0;
}

首先,我們定義了一個名為Student的結構體,包含學生的姓名、年齡和分數。
接下來,我們實現了一個名為compareStudents的自定義比較函數。
該函數根據學生的分數、年齡和姓名進行排序。
首先按照分數降序排序,如果分數相同,則按照年齡升序排序,最后按照姓名的字典序升序排序。
在主函數中,我們創建了一個存儲學生對象的vector,并初始化了幾個學生對象。
然后,我們使用std::sort函數對學生對象進行排序,傳入自定義的比較函數作為參數。
最后,我們遍歷排序后的學生對象,并輸出姓名、年齡和分數。

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

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

相關文章

論文詳解 ——《SNR-Aware Low-light Image Enhancement》

文章目錄 Abstract1.Introduction2. Related Work3. Our Method3.1 Long- and Short-range Branches3.2 SNR-based Spatially-varying Feature Fusion3.3 SNR-guided Attention in Transformer3.4 Loss Function 4. Experiments4.1. Datasets and Implementation Details4.2 Co…

SpringBoot | 使用newWorkStealingPool和CompletableFuture進行并發異步處理

關注wx&#xff1a; CodingTechWork 需求 一個列表操作需要異步處理每個元素&#xff0c;最終需要將列表各個元素的操作結果統一返回&#xff0c;無需關注該列表中的順序執行。這個線程池不會保證任務的順序執行&#xff0c;即為WorkStealing搶占式的工作。 開發模板 線程池…

基于SpringBoot實現MySQL備份與還原

基于SpringBoot實現MySQL備份與還原&#xff0c;需求是在頁面上對所有的平臺數據執行備份和恢復操作&#xff0c;那么就需要使用代碼去調用MySQL備份和恢復的指令&#xff0c;下面是具體實現步驟&#xff1b; MySQL備份表設計 CREATE TABLE IF NOT EXISTS mysql_backups (id …

6.1 安全漏洞與網絡攻擊

數據參考&#xff1a;CISP官方 目錄 安全漏洞及產生原因信息收集與分析網絡攻擊實施后門設置與痕跡清除 一、安全漏洞及產生原因 什么是安全漏洞 安全漏洞也稱脆弱性&#xff0c;是計算機系統存在的缺陷 漏洞的形式 安全漏洞以不同形式存在漏洞數量逐年遞增 漏洞產生的…

前端開發:數組對象判斷重復的方法詳解

前言 在前端開發過程中,關于數據處理是非常常用的操作,尤其是通過算法處理從后端獲取的數據甚為重要。而且在前端開發中,兩大類型的數據處理是必備的:數組和對象。與其說是數據處理,不如說是數組和對象的處理。實際開發中,關于數組數據的處理所占比例更高,尤其是涉及到表…

使用Flask.Request的方法和屬性,獲取get和post請求參數(二)

1、Flask中的request 在Python發送Post、Get等請求時&#xff0c;我們使用到requests庫。Flask中有一個request庫&#xff0c;有其特有的一些方法和屬性&#xff0c;注意跟requests不是同一個。 2、Post請求&#xff1a;request.get_data() 用于服務端獲取客戶端請求數據。注…

理解ConcurrentSkipListMap(有點類似于并發的TreeMap)

是一個分層的結構。 從最上面開始查找&#xff0c;最后層層往下查。 插入和刪除有可能會引起節點Level的變更。 key是有序的&#xff0c;因此可以看做是并發的TreeMap

ubuntu18.04下配置muduoC++11環境

1.安裝muduo依賴的編譯工具及庫 Cmake sudo apt-get install cmakeBoost sudo apt-get install libboost-dev libboost-test-devcurl、c-ares DNS、google protobuf sudo apt-get install libcurl4-openssl-dev libc-ares-dev sudo apt-get install protobuf-compiler libp…

帶你了解SpringBoot支持的復雜參數--自定義對象參數-自動封裝

&#x1f600;前言 本篇博文是關于SpringBoot 在響應客戶端請求時支持的復雜參數和自定義對象參數&#xff0c;希望您能夠喜歡&#x1f60a; &#x1f3e0;個人主頁&#xff1a;晨犀主頁 &#x1f9d1;個人簡介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章…

go struct 的常見問題

go struct 的常見問題 1. 什么是struct&#xff1f;2. 如何聲明、定義和創建一個struct&#xff1f;3. struct和其他數據類型&#xff08;如數組、切片、map等&#xff09;有什么區別&#xff1f;4. 如何訪問struct字段&#xff1f;5. struct是否支持繼承&#xff0c;是否支持重…

JavaWeb_xml

文章目錄 1.xml是什么&#xff1f;2.xml的用途 1.xml是什么&#xff1f; xml 是可擴展的標記性語言 2.xml的用途 1、用來保存數據&#xff0c;而且這些數據具有自我描述性 2、它還可以做為項目或者模塊的配置文件 3、還可以做為網絡傳輸數據的格式&#xff08;現在 JSON 為主…

【Github】SourceTree技巧匯總

sourceTree登錄github賬戶 會跳轉到瀏覽器端 按照Git Flow 初始化倉庫分支 克隆遠程倉庫到本地 推送變更到遠程倉庫 合并分支 可以看到目前的本地分支&#xff08;main、iOS_JS&#xff09;和遠程分支&#xff08;origin/main、origin/HEAD、origin/iOS_JS&#xff09;目前所處…

5134. 簡單判斷

文章目錄 Question輸入樣例1&#xff1a; 3 7 0 輸出樣例1&#xff1a; IdeasCode Question 給定三個非負整數 x,y,z &#xff0c;請你按如下要求進行判斷并輸出相應結果&#xff1a; 如果 x>yz &#xff0c;則輸出 。 如果 y>xz &#xff0c;則輸出 -。 如果 xy 且 z0…

pip install總是報錯:ValueError: Trusted host URL must include a host part: ‘#‘

一、問題現象 報錯信息如下&#xff1a; Traceback (most recent call last):File "/user_name/anaconda3/bin/pip", line 11, in <module>sys.exit(main())^^^^^^File "/user_name/anaconda3/lib/python3.11/site-packages/pip/_internal/cli/main.py&…

14_基于Flink將pulsar數據寫入到HBase

3.7.基于Flink將數據寫入到HBase 3.7.1.編寫Flink完成數據寫入到Hbase操作, 完成數據備份, 便于后續進行即席查詢和離線分析 3.7.1.1.HBase基本介紹 hbase是基于Google發布bigTable論文產生一款軟件, 是一款noSQL型數據, 不支持SQL. 不支持join的操作, 沒有表關系, 不支持事…

Codeforces 757F. Team Rocket Rises Again 最短路 + 支配樹

題意&#xff1a; 給你 n 個點&#xff0c; m 條雙向邊&#xff0c;求爆了某個點后&#xff0c;從s出發的最短路距離&#xff0c;會改變最多的數量。 分析&#xff1a; 建出最短路樹&#xff08;DAG&#xff09;之后&#xff0c;在最短路樹上跑一下支配樹&#xff0c;找出支…

鏈表OJ詳解

&#x1f495;人生不滿百&#xff0c;常懷千歲憂&#x1f495; 作者&#xff1a;Mylvzi 文章主要內容&#xff1a;鏈表oj詳解 題目一&#xff1a;移除元素 題目要求&#xff1a; 畫圖分析&#xff1a; 代碼實現&#xff1a; struct ListNode* removeElements(struct List…

flutter項目 環境搭建

開發flutter項目 搭建工具環境 flutter項目本身 所需開發工具環境 flutter 谷歌公司開發 系統支持庫 鏡像庫 搭建流程&#xff1a; flutter 官網&#xff1a; https://flutter.dev/community/china //步驟1 .bash_profile touch .bash_profile pwd /Users/haijunyan open ~ e…

商品首頁(sass+git本地初始化)

目錄 安裝sass/sass-loader 首頁(vue-setup) 使用git本地提交 同步遠程git庫 安裝sass/sass-loader #安裝sass npm i sass -D#安裝sass-loader npm i sass-loader10.1.1 -D 首頁(vue-setup) <template><view class"u-wrap"><!-- 輪播圖 --><…