STL—list

来源:http://www.cnblogs.com/zxiner/archive/2017/07/18/7202558.html
-Advertisement-
Play Games

前面我們分析了vector,這篇介紹STL中另一個重要的容器list list的設計 list由三部分構成:list節點、list迭代器、list本身 list節點 list是一個雙向鏈表,所以其list節點中有前後兩個指針。如下: list迭代器 前面我們說過vector是利用其記憶體分配類型成員給 ...


前面我們分析了vector,這篇介紹STL中另一個重要的容器list

list的設計

list由三部分構成:list節點、list迭代器、list本身

list節點

list是一個雙向鏈表,所以其list節點中有前後兩個指針。如下:

// list節點
template <typename T>
struct __list_node
{
        typedef void* void_pointer;
        void_pointer prev; // 指向前一個節點
        void_pointer next; // 指向下一個節點
        T data; // 節點的值
};

list迭代器

前面我們說過vector是利用其記憶體分配類型成員給vector分配一大塊記憶體,而其迭代器是原始指針,所以其迭代器的移動就是指針的移動,vector那樣通過指針的移動就能得到下一個元素,不需要特別設計。而list是鏈表結構,鏈表中每個節點的記憶體不連續,list的迭代器就是對外隱藏了從一個節點是如何移動到下一個節點的具體細節,使得外部只要將迭代器自增或自減就能得到相鄰的節點。

list迭代器只有一個指向鏈表節點的指針數據成員。如下:

        typedef __list_node<T>* link_type;

        link_type node;  // point to __list_node

下麵是迭代器的前置自增和前置自減運算符的源碼,可以看到是通過節點的前向和後向指針來完成從一個節點移動到另一個節點:

        self& operator++() { node = (link_type)(*node).next; return *this;}
        self& operator--() { node = (link_type)(*node).prev; return *this;}

list

和vector一樣,list也有個空間配置器的類型成員,通過該類型來為list的每個節點分配記憶體,並且通過該類型成員將外部指定的節點數目轉換為相應節點所需的記憶體所以list的記憶體模型是每個鏈表節點分配一塊單獨的記憶體,然後將每個節點連接起來。而vector的記憶體模型是分配一大塊連續的記憶體。如下:

          // 空間配置器
          typedef simple_alloc<list_node, alloc> list_node_allocator;

 

實際上,list不僅是一個雙向鏈表,而且還是一個環狀的雙向鏈表。為了設計的方便,在list中放置一個node指針,該指針指向一個空白節點,該空白節點的下一個節點是鏈表中起始節點,而鏈表的尾節點的下一個節點為該空白節點。雖然list底層是一個環狀雙向鏈表,但通過這樣設計後對外就表現出一個普通的雙向鏈表,符合一般習慣。這樣設計還有很多好處,比如快速得到鏈表的首尾節點。如下。

private:
        //指向空白節點
        link_type               node;
public:
        // 通過空白節點node完成
        iterator begin() const { return (link_type)(*node).next; }
        iterator end() const { return node;}
        bool empty() const { return node->next == node; }

 

下麵我們看list內部是如何構造一個鏈表的。以我們對list的常用使用方法 list<int> lis(10)為例:

首先調用構造函數

        explicit list(size_type n)
        {
                empty_initialize();
                insert(begin(), n, T());
        }

該構造函數會先調用empty_initialize()為list分配一個空白節點,並設置前向後向指針

        void empty_initialize()
        {
                node = get_node();
                node->next = node;
                node->prev = node;
        }
        link_type get_node() { return list_node_allocator::allocate(1);}

然後構造函數會迴圈以插入相應個數的鏈表節點,每次插入時會分配一個節點大小的記憶體,然後對這塊記憶體初始化,註意插入位置是在指定位置之前插入。由於list的記憶體模型和vector記憶體模型的區別,vector每次插入時由於可能會造成記憶體的重新配置,會造成原先所有的迭代器失效。而list的插入只是為新節點分配記憶體,並將其添加到鏈表中,對鏈表中其他節點的記憶體不會造成影響,所以list的插入則不會引起迭代器失效。如下。

template <typename T>
void
list<T>::insert(iterator position, size_type n, const T& x)
{
        for (; n > 0; --n)
                insert(position, x);
}

template
<typename T> void list<T>::insert(iterator position, const T& x)//posiiton之前插入 { link_type tmp = create_node(x); tmp->next = position.node; tmp->prev = position.node->prev; (link_type(position.node->prev))->next = tmp; position.node->prev = tmp; }
link_type create_node(
const T& x) { link_type p = get_node(); construct(&p->data, x); return p; }
link_type get_node() {
return list_node_allocator::allocate(1);}

 

(全文完)

附: STL系列文章:http://www.cnblogs.com/zxiner/p/7197402.html 一款簡易版STL的實現,項目地址:https://github.com/zinx2016/MiniSTL/tree/master/MiniSTL    
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目前國內常見的第三方開放平臺有: QQ開放平臺 微信開放平臺 新浪微博開放平臺 我們可以通過集成這些第三方平臺來實現: 第三方登錄 內容分享到第三方平臺 獲取第三方平臺用戶資源 ...... 下麵以新浪微博開放平臺為例看下Java系統具體的集成步驟,QQ和微信類似,只需少許修改(具體請參考源碼中示例 ...
  • 簡單看一下描述,例子最重要。 1、getPath(): 返回定義時的路徑,(就是你寫什麼路徑,他就返回什麼路徑) 2、getAbsolutePath(): 返回絕對路徑,但不會處理“.”和“..”的情況 3、getCanonicalPath(): 返回的是規範化的絕對路徑,相當於將getAbsolu ...
  • 上周, 我們談論了關於Java8的新特性有那些, 什麼是函數式編程, 什麼是Lambda表達式, 這周讓我們繼續談論這些新特性.本周, 我們會聊一下什麼是Stream API, 以及什麼是Optional."Stream API你讓我想重寫我以前的所有代碼","使用Optional讓你的應用從此不再... ...
  • 題目鏈接 Problem Description You are a rich person, and you think your wallet is too heavy and full now. So you want to give me some money by buying a lov ...
  • 什麼是泛型,有什麼用? 先運行下麵的代碼: 上面的代碼稍微修改下: 對比上面的代碼,沒加入泛型的時候,在程式運行期才發現問題,而加入了泛型則在程式編譯期就發現了,這就是泛型的優勢所在。 在第二段代碼中,泛型就好象是在告訴編譯器:這裡聲明的變數c只跟Date類型進行比較,如果跟別的類型比較,那麼就不能 ...
  • Description osu 是一款群眾喜聞樂見的休閑軟體。 我們可以把osu的規則簡化與改編成以下的樣子: 一共有n次操作,每次操作只有成功與失敗之分,成功對應1,失敗對應0,n次操作對應為1個長度為n的01串。在這個串中連續的 X個1可以貢獻X^3 的分數,這x個1不能被其他連續的1所包含(也 ...
  • 轉自:http://blog.csdn.net/xiaoyusmile/article/details/5420252 1. 變數的定義、聲明 變數的聲明有兩種情況: 一種是需要建立存儲空間的。例如:int a。在聲明的時候就已經建立了存儲空間。這種聲明是"定義性聲明(defining declar ...
  • 自學到java的異常時,有一些自己的理解,現在總結一下。 1.為什麼要使用異常 剛開始估計很多初學者和我一樣,不理解為什麼要異常,什麼throws拋出異常,還要catch接住好麻煩的樣子,通過一個簡單的例子來理解一下。 這裡只是一個簡單的異常條件,園的半徑不可能小於等於0的,如果直接用if判斷然後處 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...