list的模擬實現和反向迭代器的底層

1:list的模擬實現

1:鏈表的節點

對于list的模擬實現,我們需要先定義一個節點的類可以使用(class也可以使用struct)

// List的節點類
template<class T>
struct ListNode
{ListNode(const T& val = T()){_pPre = nullptr;_pNext = nullptr;_val = val;}ListNode<T>* _pPre;ListNode<T>* _pNext;T _val;
};

上面的結構體和我們模擬實現鏈表的代碼基本上差不多,只不過將初始化化成了構造函數,并且將鏈表封裝成一個類并且提供對于鏈表的操作。

2:鏈表的迭代器

為什么我們現在就需要學習鏈表的迭代器,那是因為除了我們在容器外使用迭代器,我們鏈表容器內部本身也使用迭代器完成很多操作。

//List的迭代器類
template<class T, class Ref, class Ptr>
//T是節點儲存的數據類型,Ref是T的引用T&,Ptr是T的指針T*
struct ListIterator
{typedef ListNode<T>* PNode;typedef ListIterator<T, Ref, Ptr> Self;//注意Self的重命名是定義的迭代器自己typedef Ref reference; //為反向迭代器做鋪墊 typedef Ptr pointer;//為反向迭代器做鋪墊ListIterator(PNode pNode = nullptr) : _pNode(pNode) {}ListIterator(const Self& l) :_pNode(l._pNode) {}T& operator*(){return _pNode->_val;}T* operator->(){return &(_pNode->_val);}Self& operator++(){_pNode = _pNode->_pNext;return *this;}Self operator++(int){Self tmp(_pNode);_pNode = _pNode->_pNext;return tmp;}Self& operator--(){_pNode = _pNode->_pPre;return *this;}Self operator--(int){Self tmp(_pNode);_pNode = _pNode->_pPre;return tmp;}bool operator!=(const Self& l) const{return _pNode != l._pNode;}bool operator==(const Self& l) const{return _pNode == l._pNode;        }PNode _pNode;
};

為什么提供了三個模版參數,因為在對于迭代器自己操作中,可能需要返回T的引用或者T的地址,比如*和->的運算符重載。

在迭代器里面,本質上就是定義一個ListNode*<T> 的一個指針,來對鏈表進行操作。

3:鏈表的增刪查改

template<class T>
class list
{typedef ListNode<T> Node;typedef Node* PNode;
public:typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&, const T*> const_iterator;typedef Reverse_iterator<iterator> reverse_iterator;//反向迭代器typedef Reverse_iterator<const_iterator> const_reverse_iterator;//反向迭代器
public:///// List的構造list(){CreateHead();}list(int n, const T& value = T()){CreateHead();for (int i = 0; i < n; i++){push_back(value);}}template <class Iterator>list(Iterator first, Iterator last){CreateHead();while (first != last){push_back(*first);first++;}}list(const list<T>& l){CreateHead();list<T> tmp(l.begin(), l.end());swap(tmp);}list<T>& operator=(const list<T> l){swap(l);return *this;}~list(){clear();delete _pHead;_pHead = nullptr;}///// List Iteratoriterator begin(){return iterator(_pHead->_pNext);}iterator end(){return iterator(_pHead);}const_iterator begin() const{return const_iterator(_pHead->_pNext);}const_iterator end() const{return const_iterator(_pHead);}reverse_iterator rbegin(){return reverse_iterator(end());}reverse_iterator rend(){return reverse_iterator(begin());}///// List Capacitysize_t size()const{auto it = begin();size_t count = 0;while (it != end()){it++;count++;}return count;}bool empty()const{return _pHead->_pNext == _pHead;}// List AccessT& front(){return _pHead->_pNext->_val;}const T& front()const{return _pHead->_pNext->_val;}T& back(){return _pHead->_pPre->_val;}const T& back()const{return _pHead->_pPre->_val;}// List Modifyvoid push_back(const T& val){ insert(end(), val);}void pop_back(){erase(--end()); }void push_front(const T& val) { insert(begin(), val); }void pop_front(){ erase(begin()); }// 在pos位置前插入值為val的節點iterator insert(iterator pos, const T& val){Node* newnode = new Node(val);Node* pcur = pos._pNode;newnode->_pPre = pcur->_pPre;newnode->_pNext = pcur;pcur->_pPre->_pNext = newnode;pcur->_pPre = newnode;return iterator(newnode);}// 刪除pos位置的節點,返回該節點的下一個位置iterator erase(iterator pos){        assert(size()>0);       Node* pcur = pos._pNode;Node* pret = pcur->_pNext;pcur->_pPre->_pNext = pcur->_pNext;pcur->_pNext->_pPre = pcur->_pPre;delete pcur;return iterator(pret);}void clear(){Node* cur = _pHead->_pNext;while (cur != _pHead){_pHead->_pNext = cur->_pNext;delete cur;cur = _pHead->_pNext;}_pHead->_pNext = _pHead->_pPre = _pHead;}void swap(list<T>& l){std::swap(_pHead, l._pHead);}
private:void CreateHead(){_pHead = new ListNode<T>; //這里是模版_pHead->_pPre = _pHead;_pHead->_pNext = _pHead;}PNode _pHead;
};
1:list的構造

對于list的構造我們實現了四種構造方式,第一是直接構造一個空鏈表,第二是使用n個相同元素構造鏈表,第三是使用迭代器來構造鏈表,第四就是使用list本身構造鏈表,額外重載運算符=來實現鏈表。

2:list的迭代器在類中的返回

我們可以很直觀的看到迭代器在類中是返回的什么。

3:list的容量判斷

我們之間在類的內部使用迭代器便利鏈表來計算鏈表大小。

4:增刪操作

邏輯和以前對于鏈表的實現上大型不差,出了額外增加了幾個接口然后使用迭代器。

2:反向迭代器的實現

反向迭代器本質上就是正向迭代器的封裝

 template<class Iterator>struct Reverse_iterator{public:
// 注意:此處typename的作用是明確告訴編譯器,Ref是Iterator類中的類型,而不是靜態成員變量
// 否則編譯器編譯時就不知道Ref是Iterator中的類型還是靜態成員變量
// 因為靜態成員變量也是按照 類名::靜態成員變量名 的方式訪問的typedef typename Iterator::reference Ref;  // 從正向迭代器提取typedef typename Iterator::pointer Ptr;typedef Reverse_iterator<Iterator> Self;public:Reverse_iterator(Iterator it = nullptr) :_it(it) {}Ref operator*(){Iterator temp(_it);--temp;return *temp;}Ptr operator->(){return &(operator*());}Self operator++(){--_it;return *this;}Self operator++(int){Self temp(*this);--_it;return temp;}Self operator--(){++_it;return *this;}Self operator--(int){Self temp(*this);++_it;return temp;}bool operator!=(const Self& l)const{return _it != l._it;}bool operator==(const Self& l)const{return _it == l._it;}Iterator _it;};

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

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

相關文章

數據加載與保存

通用方式? SparkSQL提供了通用的數據加載方式&#xff0c;使用spark.read.loa方法&#xff0c;并可通過format指定數據類型&#xff08;如csv、jdbc、json、orc、parquet、textFile&#xff09;。 load方法后需傳入數據路徑&#xff08;針對csv、jdbc、json、orc、parquet、…

7 編譯型語言、解釋型語言與混合型語言的深度解析:以 C、Java、Python 為例

在編程領域&#xff0c;語言的執行方式是其設計哲學的核心體現&#xff0c;直接影響著性能、可移植性和開發效率。本文將深入剖析編譯型語言&#xff08;以 C 語言為例&#xff09;、解釋型語言&#xff08;以 Python 為例&#xff09;和混合型語言&#xff08;以 Java 為例&am…

Edge瀏覽器安卓版流暢度與廣告攔截功能評測【不卡還凈】

安卓設備上使用瀏覽器的體驗&#xff0c;很大程度取決于兩個方面。一個是滑動和頁面切換時的反應速度&#xff0c;另一個是廣告干擾的多少。Edge瀏覽器的安卓版本在這兩方面的表現比較穩定&#xff0c;適合日常使用和內容瀏覽。 先看流暢度。Edge在中端和高端機型上啟動速度快&…

智能云圖庫-12-DDD重構

本節重點? 之前我們已經完成了本項目的功能開發。由于本項目功能豐富、代碼量大&#xff0c;如果是在企業中維護開發的項目&#xff0c;傳統的 MVC 架構可能會讓后續的開發協作越來越困難。所以本節魚皮要從 0 帶大家學習一種新的架構設計模式 —— DDD 領域驅動設計。 大綱…

量子安全郵件系統 —— 郵件回溯密鑰銷毀機制

這里寫目錄標題 量子安全郵件系統 —— 郵件回溯密鑰銷毀機制一、項目背景與簡介二、理論基礎2.1 密鑰銷毀的重要性2.2 時間衰減與回溯銷毀2.3 安全日志與報警機制三、系統架構設計3.1 模塊劃分3.2 系統架構圖(Mermaid示意圖)四、關鍵算法與實現流程4.1 密鑰生成與存儲4.2 郵…

個人博客系統后端 - 用戶信息管理功能實現指南(上)

本文記錄了如何實現用獲取戶信息&#xff0c;用戶信息更新&#xff0c;用戶頭像上傳三大基礎功能 先上接口實現截圖&#xff1a; 一、項目結構概覽 先介紹一下 個人博客系統采用了標準的 Spring Boot 項目結構&#xff0c;用戶功能相關的文件主要分布在以下幾個目錄&#xff1a…

趣味編程之分布式系統:負載均衡的“雨露均沾“藝術

#此篇文章由Deepseek大力支持&#x1f60b; 凌晨三點&#xff0c;西二旗某火鍋店后廚—— “羊肉卷走3號桌&#xff01;” “肥牛卷去7號&#xff01;” “蝦滑優先給VIP區&#xff01;” 我蹲在傳菜口的監控屏幕前&#xff0c;看著機器人服務生們忙而不亂地穿梭。突然間&am…

Linux——信號(1)信號的產生

我們在講進程的多種狀態時提到過&#xff0c;一個進程的退出有三種情況&#xff1a;正常退出&#xff0c;結果出錯退出&#xff08;代碼也執行完了&#xff09;&#xff0c;異常終止退出&#xff08;代碼未執行完&#xff09;&#xff0c;其中最后一種退出相當于進程在運行時&a…

LeetCode 2919 使數組變美的最小增量運算數

動態規劃解題&#xff1a;最小操作次數使數組變為美麗數組 問題描述 給定一個下標從0開始、長度為n的整數數組nums和一個整數k。你可以對數組中的任意一個元素進行加1操作&#xff0c;操作次數不限。如果數組中任意長度大于或等于3的子數組的最大值都大于或等于k&#xff0c;…

計算生物學在中國的發展情況?

李升偉 整理 計算生物學在中國的發展呈現出多方面積極態勢&#xff0c;具體表現如下&#xff1a; 發展概述&#xff1a; 上海發布了醫用AI發展的專項方案&#xff0c;特別強調了腦科學與計算生物學的前沿領域。這表明政府有意推動該領域的技術進步和技術合作平臺建設。國內的…

Linux之文件內容顯示(cat、grep、cut、sort、uniq、tr)

&#x1f3af; 本文專欄&#xff1a;Linux &#x1f680; 作者主頁&#xff1a;小度愛學習 1、瀏覽普通文件內容 命令常用選項說明cat-n 對輸出內容中的所有行標注行號&#xff1b;-b 對輸出內容中的非空行標注行號。查看文本文件的內容head-num 指定需要顯示文件num行的內容。…

3DS 轉 STL 全攻略:傳統工具與迪威模型網在線轉換深度解析

在 3D 建模與 3D 打印的技術領域中&#xff0c;常常會遇到需要將不同格式的文件進行轉換的情況。其中&#xff0c;把 3DS 文件轉換為 STL 格式是較為常見的操作。3DS 文件作為一種舊版 Autodesk 3D Studio 使用的 3D 圖像格式&#xff0c;存儲著豐富的信息&#xff0c;包括網格…

IoT FEM射頻前端模組芯片(2.4G PA)三伍微電子GSR2401 兼容替代RFX2401

型號&#xff1a;GSR2401應用&#xff1a;適用于藍牙&#xff08;BT&#xff09;、ZigBee及物聯網&#xff08;IoT&#xff09;設備 功能&#xff1a;集成了功率放大器&#xff08;PA&#xff09;、開關&#xff08;Switch&#xff09;和低噪聲放大器&#xff08;LNA&#xff…

Missashe考研日記-day22

Missashe考研日記-day22 1 專業課408 學習時間&#xff1a;3h學習內容&#xff1a; 先把昨天關于進程調度的課后習題做了&#xff0c;然后花了挺長時間預習OS的最最最最重要的一部分——同步與互斥問題&#xff0c;這部分大二上課的時候就懵懵懂懂的&#xff0c;得認真再領悟…

2025年最新Web安全(面試題)

活動發起人小虛竹 想對你說&#xff1a; 這是一個以寫作博客為目的的創作活動&#xff0c;旨在鼓勵大學生博主們挖掘自己的創作潛能&#xff0c;展現自己的寫作才華。如果你是一位熱愛寫作的、想要展現自己創作才華的小伙伴&#xff0c;那么&#xff0c;快來參加吧&#xff01…

Qt QML - qmldir使用方法詳解

以實際例子看qmldir的使用 1.搞一個qmldir2.讓QML找到你的qmldir &#xff08;重點&#xff09;.pro 工程文件QQmlApplicationEngine加載主QML處 3.用起來你的模塊 qmldir是Qt QML模塊化的基石&#xff0c;其設計初衷是為解決QML文件的組織、復用和依賴管理問題,。只需要在每個…

# Shell腳本參數設計規范(DeepSeek指導)

Shell腳本參數設計規范&#xff08;DeepSeek指導&#xff09; 文章目錄 Shell腳本參數設計規范&#xff08;DeepSeek指導&#xff09;A 我問&#xff1a;Q DeepSeek回答&#xff1a;**命令行參數表示規范****標準化表示示例**情況1&#xff1a;必選選項參數值情況2&#xff1a;…

MQTT協議:IoT通信的輕量級選手

文章總結&#xff08;幫你們節約時間&#xff09; MQTT協議是一種輕量級的發布/訂閱通信協議。MQTT通信包括連接建立、訂閱、發布和斷開等過程。MQTT基于TCP/IP&#xff0c;其通信過程涉及多種控制包和數據包。ESP32S3可以通過MQTT協議接收消息來控制IO9引腳上的LED。 想象一…

數據結構——反射、枚舉以及lambda表達式

1. 反射 Java的反射&#xff08;reflection&#xff09;機制是在運?時檢查、訪問和修改類、接?、字段和?法的機制&#xff1b;這種動態獲取信息以及動態調?對象?法的功能稱為java語?的反射&#xff08;reflection&#xff09;機制。 用途 1. 框架開發 2. 注解處理 3.…

C語言教程(十):C 語言函數詳解

一、引言 在 C 語言中&#xff0c;函數是一組執行特定任務的代碼塊。通過將復雜的程序邏輯劃分為多個函數&#xff0c;不僅能提高代碼的可讀性、可維護性&#xff0c;還便于代碼的復用。無論是簡單的數學計算&#xff0c;還是復雜的系統操作&#xff0c;函數都發揮著核心作用。…