最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++中l(wèi)ist實(shí)現(xiàn)雙向循環(huán)鏈表詳細(xì)解析

 更新時(shí)間:2026年01月15日 10:57:08   作者:yuuki233233  
雙向循環(huán)鏈表是一種重要的線(xiàn)性數(shù)據(jù)結(jié)構(gòu),支持前后雙向遍歷,適用于頻繁插入刪除和高效訪(fǎng)問(wèn)的場(chǎng)景,這篇文章主要介紹了C++中l(wèi)ist實(shí)現(xiàn)雙向循環(huán)鏈表詳細(xì)解析的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在上一篇中,我們吃透了 vector 的底層實(shí)現(xiàn) —— 作為動(dòng)態(tài)連續(xù)數(shù)組,它憑借 “隨機(jī)訪(fǎng)問(wèn)” 的優(yōu)勢(shì)成為日常開(kāi)發(fā)的首選,但也存在無(wú)法回避的短板:頭部 / 中間插入刪除需要挪動(dòng)大量元素,時(shí)間復(fù)雜度高達(dá) O (n);擴(kuò)容時(shí)的內(nèi)存拷貝也會(huì)帶來(lái)額外性能開(kāi)銷(xiāo)。

而 list 作為 STL 中另一核心容器,恰好彌補(bǔ)了 vector 的這些不足:它基于雙向循環(huán)鏈表實(shí)現(xiàn),任意位置的插入刪除僅需修改指針指向,時(shí)間復(fù)雜度可降至 O (1)。本章我們將從鏈表的底層結(jié)構(gòu)出發(fā),一步步實(shí)現(xiàn)一個(gè)功能完整的 list 類(lèi),帶你掌握:

  1. 雙向循環(huán)鏈表的設(shè)計(jì)邏輯與核心優(yōu)勢(shì)
  2. list 與 vector 的底層差異及適用場(chǎng)景
  3. 鏈表迭代器的特殊實(shí)現(xiàn)(為什么不能直接用指針?)

一、list 容器的核心特性

list 是 STL 中以雙向循環(huán)鏈表為底層結(jié)構(gòu)的序列式容器,其核心特性包括:

  1. 非連續(xù)存儲(chǔ):元素在內(nèi)存中離散分布,通過(guò)指針連接形成鏈表
  2. 雙向遍歷:每個(gè)節(jié)點(diǎn)包含前驅(qū)和后繼指針,支持向前 / 向后遍歷
  3. 高效增刪:任意位置的插入 / 刪除操作僅需修改指針指向,時(shí)間復(fù)雜度為 O (1)
  4. 無(wú)擴(kuò)容開(kāi)銷(xiāo):無(wú)需預(yù)先分配內(nèi)存,元素增減不會(huì)導(dǎo)致大規(guī)模內(nèi)存拷貝
  5. 迭代器特殊:迭代器不是原生指針,需重載 ++/-- 等運(yùn)算符實(shí)現(xiàn)節(jié)點(diǎn)跳轉(zhuǎn)

與 vector 的核心差異

特性vectorlist
存儲(chǔ)方式連續(xù)內(nèi)存空間離散鏈表節(jié)點(diǎn)
隨機(jī)訪(fǎng)問(wèn)支持(O (1))不支持(需遍歷)
插入刪除效率中間插入刪除效率低(O (n))任意位置效率高(O (1))
內(nèi)存開(kāi)銷(xiāo)?。▋H存儲(chǔ)數(shù)據(jù))大(需額外存儲(chǔ)指針)
擴(kuò)容機(jī)制自動(dòng)擴(kuò)容(可能有拷貝)無(wú)擴(kuò)容機(jī)制

二、list 的迭代器使用

list 的迭代器是實(shí)現(xiàn)鏈表遍歷的關(guān)鍵,由于其非連續(xù)存儲(chǔ)特性,迭代器的實(shí)現(xiàn)與 vector 有本質(zhì)區(qū)別。

方式適用場(chǎng)景
begin() + end()正向迭代器,begin() 指向首元素,end() 指向尾元素下一位r
rbegin() + rend()反向迭代器,rbegin() 指向尾元素,rend() 指向首元素前一位
#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> l = {1, 2, 3, 4, 5};
    
    // 正向迭代器遍歷
    cout << "正向遍歷: ";
    for (list<int>::iterator it = l.begin(); it != l.end(); ++it) {
        cout << *it << " ";
    }
    cout << endl;  // 輸出:1 2 3 4 5
    
    // 反向迭代器遍歷
    cout << "反向遍歷: ";
    for (list<int>::reverse_iterator rit = l.rbegin(); rit != l.rend(); ++rit) {
        cout << *rit << " ";
    }
    cout << endl;  // 輸出:5 4 3 2 1
	
    return 0;
}

注意list 的迭代器不支持隨機(jī)訪(fǎng)問(wèn)(如 it + 3 操作),只能通過(guò) ++/-- 逐步移動(dòng)。

三、list 的常見(jiàn)構(gòu)造方式

list 提供了多種構(gòu)造函數(shù),滿(mǎn)足不同場(chǎng)景下的初始化需求:

方式適用場(chǎng)景
list()無(wú)參構(gòu)造,創(chuàng)建空鏈表
list(size_type n, const T& val = T())構(gòu)造包含 n 個(gè) val 元素的鏈表
list(const list& x)拷貝構(gòu)造,創(chuàng)建 x 的副本
list(InputIterator first, InputIterator last)用 [first, last) 區(qū)間元素構(gòu)造鏈表
list(initializer_list< T > ilist)初始化列表構(gòu)造(C++11)
#include <iostream>
#include <list>
using namespace std;

void printList(const list<int>& l) {
    for (auto num : l) {
        cout << num << " ";
    }
    cout << endl;
}

int main() {
    // 無(wú)參構(gòu)造
    list<int> l1;
    
    // 構(gòu)造包含5個(gè)3的鏈表
    list<int> l2(5, 3);
    printList(l2);  // 輸出:3 3 3 3 3
    
    // 迭代器區(qū)間構(gòu)造
    list<int> l3(l2.begin(), --l2.end());
    printList(l3);  // 輸出:3 3 3 3
    
    // 拷貝構(gòu)造
    list<int> l4(l3);
    printList(l4);  // 輸出:3 3 3 3
    
    // 初始化列表構(gòu)造(C++11)
    list<int> l5{1, 2, 3, 4, 5};
    printList(l5);  // 輸出:1 2 3 4 5
    
    return 0;
}

四、list 的容量與元素訪(fǎng)問(wèn)

list 提供了基礎(chǔ)的容量查詢(xún)和元素訪(fǎng)問(wèn)接口:

方式適用場(chǎng)景
empty()判斷鏈表是否為空,為空返回 true
size()返回鏈表中有效元素的個(gè)數(shù)
front()返回鏈表第一個(gè)元素的引用
back()返回鏈表最后一個(gè)元素的引用
max_size()返回鏈表理論上能容納的最大元素個(gè)數(shù)(很少使用)
#include <iostream>
#include <list>
using namespace std;

int main() {
    list<int> l = {10, 20, 30, 40, 50};
    
    cout << "鏈表是否為空: " << (l.empty() ? "是" : "否") << endl;  // 輸出:否
    cout << "鏈表元素個(gè)數(shù): " << l.size() << endl;  // 輸出:5
    cout << "第一個(gè)元素: " << l.front() << endl;  // 輸出:10
    cout << "最后一個(gè)元素: " << l.back() << endl;  // 輸出:50
    
    // 修改首尾元素
    l.front() = 100;
    l.back() = 500;
    for (auto num : l) {
        cout << num << " ";
    }
    // 輸出:100 20 30 40 500
    
    return 0;
}

注意list 不支持 operator[] 下標(biāo)訪(fǎng)問(wèn)和隨機(jī)訪(fǎng)問(wèn),只能通過(guò)迭代器或 front()/back() 訪(fǎng)問(wèn)元素。

五、list 的增刪查改操作

list 提供了豐富的元素操作接口,尤其擅長(zhǎng)插入和刪除操作:

函數(shù)聲明接口說(shuō)明
push_front(const T& val)在鏈表頭部插入元素 val
pop_front()刪除鏈表頭部元素
push_back(const T& val)在鏈表尾部插入元素 val
pop_back()刪除鏈表尾部元素
insert(iterator pos, const T& val)在 pos 位置前插入元素 val
insert(iterator pos, size_type n, const T& val)在 pos 位置前插入 n 個(gè) val
insert(iterator pos, InputIterator first, InputIterator last)在 pos 位置前插入 [first, last) 區(qū)間元素
erase(iterator pos)刪除 pos 位置的元素,返回下一個(gè)元素的迭代器
erase(iterator first, iterator last)刪除 [first, last) 區(qū)間元素,返回下一個(gè)元素的迭代器
swap(list& x)交換當(dāng)前鏈表與 x 中的元素
clear()清空鏈表中的所有元素
remove(const T& val)刪除鏈表中所有值為 val 的元素
unique()刪除連續(xù)的重復(fù)元素(只保留一個(gè))
sort()對(duì)鏈表元素進(jìn)行排序(升序)
reverse()反轉(zhuǎn)鏈表元素的順序
#include <iostream>
#include <list>
#include <algorithm> // 用于find算法
using namespace std;

void printList(const list<int>& l, const string& msg) {
    cout << msg << ": ";
    for (auto num : l) {
        cout << num << " ";
    }
    cout << endl;
}

int main() {
    list<int> l;
    
    // 尾插元素
    l.push_back(1);
    l.push_back(2);
    l.push_back(3);
    printList(l, "尾插后");  // 輸出:1 2 3
    
    // 頭插元素
    l.push_front(0);
    printList(l, "頭插后");  // 輸出:0 1 2 3
    
    // 查找元素(使用STL算法)
    auto it = find(l.begin(), l.end(), 2);
    if (it != l.end()) {
        // 在找到的位置前插入元素
        l.insert(it, 100);
        printList(l, "插入后");  // 輸出:0 1 100 2 3
    }
    
    // 刪除元素
    it = find(l.begin(), l.end(), 1);
    if (it != l.end()) {
        l.erase(it);
        printList(l, "刪除后");  // 輸出:0 100 2 3
    }
    
    // 排序
    l.sort();
    printList(l, "排序后");  // 輸出:0 2 3 100
    
    // 反轉(zhuǎn)
    l.reverse();
    printList(l, "反轉(zhuǎn)后");  // 輸出:100 3 2 0
    
    // 移除指定值元素
    l.remove(3);
    printList(l, "移除3后");  // 輸出:100 2 0
    
    // 清空鏈表
    l.clear();
    cout << "清空后是否為空: " << (l.empty() ? "是" : "否") << endl;  // 輸出:是
    
    return 0;
}

注意

  1. list 自帶 sort() 成員函數(shù),不建議使用 STL 中的 sort 算法(效率低)
  2. 插入操作不會(huì)使迭代器失效,刪除操作只會(huì)使被刪除元素的迭代器失效
  3. unique() 僅刪除連續(xù)的重復(fù)元素,通常需配合 sort() 使用以刪除所有重復(fù)元素

六、list的實(shí)際運(yùn)用

list 憑借其高效的插入刪除特性,適用于以下場(chǎng)景:

  1. 頻繁插入刪除的場(chǎng)景:如實(shí)現(xiàn)隊(duì)列、棧、雙向隊(duì)列等數(shù)據(jù)結(jié)構(gòu)
  2. 數(shù)據(jù)元素較大的場(chǎng)景:避免 vector 擴(kuò)容時(shí)的大量數(shù)據(jù)拷貝
  3. 需要頻繁在兩端操作的場(chǎng)景:如實(shí)現(xiàn) LRU 緩存淘汰算法

七、總結(jié)

list 作為基于雙向循環(huán)鏈表的容器,在元素插入刪除操作上具有顯著優(yōu)勢(shì),但不支持隨機(jī)訪(fǎng)問(wèn)。使用時(shí)需根據(jù)具體場(chǎng)景選擇:

  • 需頻繁隨機(jī)訪(fǎng)問(wèn)數(shù)據(jù) → 選擇 vector
  • 需頻繁插入刪除數(shù)據(jù) → 選擇 list
  • 數(shù)據(jù)量小且訪(fǎng)問(wèn)模式不確定 → 可優(yōu)先考慮 vector(簡(jiǎn)單高效)

掌握 list 的迭代器特性和成員函數(shù)用法,能幫助我們?cè)诤线m的場(chǎng)景下寫(xiě)出更高效的代碼。在實(shí)際開(kāi)發(fā)中,合理搭配不同容器的優(yōu)勢(shì),才能發(fā)揮 STL 的最大威力。

到此這篇關(guān)于C++中l(wèi)ist實(shí)現(xiàn)雙向循環(huán)鏈表的文章就介紹到這了,更多相關(guān)C++ list雙向循環(huán)鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中的memset用法詳解

    C++中的memset用法詳解

    memset是一個(gè)初始化函數(shù),作用是將某一塊內(nèi)存中的全部設(shè)置為指定的值,本文給大家介紹C++中的memset用法,感興趣的朋友跟隨小編一起看看吧
    2023-02-02
  • 深入探究C/C++中互斥量(鎖)的實(shí)現(xiàn)原理

    深入探究C/C++中互斥量(鎖)的實(shí)現(xiàn)原理

    ? 互斥量是一種同步原語(yǔ),用于保護(hù)多個(gè)線(xiàn)程同時(shí)訪(fǎng)問(wèn)共享數(shù)據(jù),互斥量提供獨(dú)占的、非遞歸的所有權(quán)語(yǔ)義,本文將和大家一起深入探究C/C++中互斥量(鎖)的實(shí)現(xiàn)原理,感興趣的小伙伴跟著小編一起來(lái)看看吧
    2024-06-06
  • 在Qt中遍歷QStringList子集并存儲(chǔ)的三種方法

    在Qt中遍歷QStringList子集并存儲(chǔ)的三種方法

    本文介紹了在Qt中遍歷QStringList子集并存儲(chǔ)的三種方法:1)使用mid()函數(shù)提取連續(xù)范圍的元素;2)通過(guò)循環(huán)遍歷指定索引范圍;3)利用filter()函數(shù)按內(nèi)容篩選,每種方法適用于不同場(chǎng)景,需要的朋友可以參考下
    2026-01-01
  • C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字)

    C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字)

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(136.單獨(dú)的數(shù)字),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • C++11新特性之四種類(lèi)型轉(zhuǎn)換cast說(shuō)明

    C++11新特性之四種類(lèi)型轉(zhuǎn)換cast說(shuō)明

    類(lèi)型轉(zhuǎn)換是項(xiàng)目中常使用的一種語(yǔ)法規(guī)則,幾乎每個(gè)編程語(yǔ)言都不可避免的涉及到這方面,下面這篇文章主要給大家介紹了關(guān)于C++11新特性之四種類(lèi)型轉(zhuǎn)換cast說(shuō)明的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • C語(yǔ)言基礎(chǔ) strlen 函數(shù)

    C語(yǔ)言基礎(chǔ) strlen 函數(shù)

    這篇文章主要介紹了C語(yǔ)言基礎(chǔ) strlen 函數(shù),在C 語(yǔ)言中,char 字符串也是一種非常重要的數(shù)據(jù)類(lèi)型,我們可以使用 strlen 函數(shù)獲取字符串長(zhǎng)度,這就是C語(yǔ)言strlen 函數(shù)的作用,下面我們來(lái)簡(jiǎn)單介紹該內(nèi)容,需要的朋友可以參考以下
    2021-10-10
  • C++內(nèi)存對(duì)齊的實(shí)現(xiàn)

    C++內(nèi)存對(duì)齊的實(shí)現(xiàn)

    本文主要介紹了C++內(nèi)存對(duì)齊的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 使用matlab繪制七夕表白玫瑰花束

    使用matlab繪制七夕表白玫瑰花束

    又是一年七夕節(jié)要到了,每年一次直男審美MATLAB繪圖大賽開(kāi)始了,于是今年對(duì)我之前寫(xiě)的老代碼進(jìn)行了點(diǎn)優(yōu)化組合,整了個(gè)花球變花束,感興趣的小伙伴可以動(dòng)手試一試
    2023-08-08
  • C++ 重載與重寫(xiě)的區(qū)別與實(shí)現(xiàn)

    C++ 重載與重寫(xiě)的區(qū)別與實(shí)現(xiàn)

    在面向?qū)ο笳Z(yǔ)言中,經(jīng)常提到重載與重寫(xiě),本文主要介紹了C++ 重載與重寫(xiě)的區(qū)別與實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • QT中大部分部件如何使用舉例詳解

    QT中大部分部件如何使用舉例詳解

    QWidget類(lèi)是所有用戶(hù)界面對(duì)象的基類(lèi),被稱(chēng)為基礎(chǔ)窗口部件,下面這篇文章主要給大家介紹了關(guān)于QT中大部分部件如何使用的相關(guān)資料,需要的朋友可以參考下
    2022-06-06

最新評(píng)論

邵阳县| 德阳市| 宕昌县| 佛教| 遂川县| 杭锦旗| 峡江县| 惠东县| 叶城县| 塔河县| 宜阳县| 高要市| 莱西市| 大庆市| 门头沟区| 浙江省| 朝阳区| 奉节县| 泸溪县| 乌鲁木齐县| 神木县| 固始县| 达拉特旗| 华池县| 杭锦后旗| 合阳县| 辽中县| 赤壁市| 平果县| 壶关县| 正镶白旗| 平度市| 青岛市| 泗洪县| 马鞍山市| 宁蒗| 永和县| 永泰县| 景谷| 广东省| 临颍县|