list

目錄

迭代器

介紹

種類?

本質

介紹

模擬實現

注意點

代碼?


迭代器

介紹

在C++中,迭代器(Iterators)是一種用于遍歷容器(如數組、vector、list等)中元素的工具

無論容器的具體實現細節如何,訪問容器中的元素的方法都是統一的,使用者不需要知道具體實現的細節

  • 迭代器的概念類似于指針,但迭代器更為通用,可以適用于各種不同類型的容器(且不同對象的迭代器,種類也不同)
  • 迭代器在算法函數中也可以使用,這樣可以兼容不同的容器(比如sort,find),就可以使用通用的算法模板

種類?

迭代器分為幾種不同類型,每種類型對應不同的容器特性和訪問方式:

  1. 輸入迭代器(Input Iterator):僅支持從容器中讀取數據,類似于只讀操作。它們一次只能移動一個位置,不允許修改容器的元素。

  2. 輸出迭代器(Output Iterator):僅支持向容器中寫入數據,類似于只寫操作。與輸入迭代器類似,一次只能移動一個位置。

  3. 前向迭代器(Forward Iterator):支持讀取和寫入操作,并且可以多次遍歷容器。每次移動一個位置。

  4. 雙向迭代器(Bidirectional Iterator):與前向迭代器類似,但可以向前和向后移動,每次一個位置。

  5. 隨機訪問迭代器(Random Access Iterator):具有最強大的功能,可以在常量時間內跳轉到容器中的任何位置,支持讀取、寫入和算術操作

  • 這幾種迭代器互相有包含關系,比如可以使用雙向迭代器的,也可以使用隨機迭代器

  • 不同的迭代器用以支持遍歷不同類型的容器,以及限制了算法函數兼容的容器類型(比如sort就不支持list類型)
  • 每個容器都有自己對應的迭代器類型

本質

實際上都是指針,有些容器的迭代器可以直接使用指針(eg:vector),但有些不行(eg: list)

  • list的物理空間并不連續,直接使用無法實現++的效果,其他功能也不行
  • 因此就需要創建一個類,來規定迭代器的操作

介紹

list是標準模板庫(STL)提供的一個雙向帶頭鏈表容器類

上面有說,list并不支持sort,但list內部有自己的sort

  • 雖然是這樣沒錯,但既然不支持,自然有它的道理
  • 內部的sort在遇到大數據時,遠不如 "將數據拷貝到vector中,由vector使用sort排序,再將排序后的數據恢復成list"?的效率高
  • 當然,小數據的時候就不需要這些麻煩的操作了,這時候內部的sort還是很方便嘟

模擬實現

注意點

  • 迭代器封裝+結點封裝(以及進行了重命名,會有各種嵌套)
  • 結點類中有前后指針+數據,list類中有頭結點指針+結點個數,迭代器是結點指針包裝后的產物

  • const迭代器的實現 (模板參數)
  • 兩種迭代器 在list類中傳參+重命名 實例化,可以傳指針構造,也有拷貝構造

  • ' -> '符號的重載?(->重載函數返回指針,因此訪問迭代器的實際語法應為 it -> ->begin(),是編譯器簡化成了只有一個->)
  • list的多種拷貝構造

代碼?

#include <iostream>
#include <assert.h>
#include <string>using namespace std;namespace bit
{// List的節點類template <class T>struct ListNode // struct默認公有(因為不會有人去訪問結點成員的){typedef ListNode<T> *PNode;ListNode(const T &val = T()): _ppre(nullptr), _pnext(nullptr), _val(val){};PNode _ppre;PNode _pnext;T _val;};// List的迭代器類 -- 因為無法直接使用指針作為迭代器,需要手動添加功能template <class T, class Ref, class Ptr> // ref用于標記*時對象的const屬性,ptr用于標記->時返回對象的const屬性class ListIterator{public:typedef ListNode<T> *PNode;             // 指針重命名typedef ListIterator<T, Ref, Ptr> Self; // 迭代器重命名PNode _pNode; // 將指針作為迭代器的底層public: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(*this);_pNode = _pNode->_pnext;return tmp;}Self &operator--(){_pNode = _pNode->_ppre;return (*this);}Self operator--(int){Self tmp(*this);_pNode = _pNode->_ppre;return tmp;}bool operator!=(const Self &l){return _pNode != l._pNode;}bool operator==(const Self &l){return _pNode == l._pNode;}};// list類template <class T>class mylist{typedef ListNode<T> Node;typedef Node *PNode;public: // 兩種迭代器typedef ListIterator<T, T &, T *> iterator;typedef ListIterator<T, const T &, const T &> const_iterator;public:// List的構造mylist(){CreateHead();}mylist(int n, const T &value = T()){CreateHead();PNode p = _pHead;for (size_t i = 0; i < n; ++i){push_back(value);}_size += n;}template <class Iterator>mylist(Iterator first, Iterator last){CreateHead();while (first != last){push_back(*first);++first;}}mylist(const mylist<T> &l){CreateHead();for (auto c : l){push_back(c);}}mylist<T> &operator=(const mylist<T> l){swap(l);return (*this);}~mylist(){// clear();// delete[] _pHead;while (!empty()){erase(begin());}}// 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);}// List Capacitysize_t size() const{return _size;}bool empty() const{return _size == 0;}// List AccessT &front(){return *begin();}const T &front() const{return *begin();}T &back(){return *(--end());}const T &back() const{return *(--end());}// 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){PNode cur = pos._pNode;PNode pre = cur->_ppre;PNode newnode = new Node(val);newnode->_pnext = cur;pre->_pnext = newnode;cur->_ppre = newnode;newnode->_ppre = pre;_size++;return newnode;}// 刪除pos位置的節點,返回該節點的下一個位置iterator erase(iterator pos){PNode cur = pos._pNode;PNode pre = cur->_ppre, next = cur->_pnext;pre->_pnext = cur->_pnext;cur->_pnext->_ppre = pre;delete cur;--_size;return next;}void clear(){PNode cur = _pHead->_pnext;while (cur != _pHead){PNode tmp = cur;cur = cur->_pnext;delete tmp;}_size = 0;// iterator it = begin();// while (it != end())// {//     it = erase(it);// }}void swap(mylist<T> &l){std::swap(_pHead, l._pHead);std::swap(_size, l._size);}private:void CreateHead(){_pHead = new Node;_pHead->_pnext = _pHead;_pHead->_ppre = _pHead;_size = 0;}PNode _pHead;size_t _size;};
};

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

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

相關文章

在ubuntu中將dict.txt導入到數據庫sqlite3

將dict.txt導入到數據庫 #include <head.h> #include <sqlite3.h> int do_insert(int i,char *str,sqlite3 *db); int main(int argc, const char *argv[]) {//創建泵打開一個數據庫sqlite3 *db NULL;if(sqlite3_open("./my.db",&db) ! SQLITE_OK){…

【TI-CCS筆記】工程編譯配置 bin文件的編譯和生成 各種架構的Post-build配置匯總

【TI-CCS筆記】工程編譯配置 bin文件的編譯和生成 各種架構的Post-build配置匯總 TI編譯器分類 在CCS按照目錄下 有個名為${CG_TOOL_ROOT}的目錄 其下就是當前工程的編譯器 存放目錄為&#xff1a; C:\ti\ccs1240\ccs\tools\compiler按類型分為五種&#xff1a; ti-cgt-arm…

2023年排行前五的大規模語言模型(LLM)

2023年排行前五的大規模語言模型(LLM) 截至2023年&#xff0c;人工智能正在風靡全球。它已經成為熱門的討論話題&#xff0c;吸引了數百萬人的關注&#xff0c;不僅限于技術專家和研究人員&#xff0c;還包括來自不同背景的個人。人們對人工智能熱情高漲的原因之一是其在人類多…

CS5263替代停產IT6561連接DP轉HDMI音視頻轉換器ASL 集睿致遠CS5263設計電路原理圖

ASL集睿致遠CS5263是一款DP1.4到HDMI2.0b轉換器芯片&#xff0c;設計用于將DP1.4源連接到HDMI2.0b接收器。 CS5263功能特性&#xff1a; DP接口包括4條主通道、輔助通道和HPD信號。接收器支持每通道5.4Gbps&#xff08;HBR2&#xff09;數據速率。DP接收機結合了HDCP1.4和HDCP…

NVIDIA Omniverse與GPT-4結合生成3D內容

全球各行業對 3D 世界和虛擬環境的需求呈指數級增長。3D 工作流程是工業數字化的核心&#xff0c;開發實時模擬來測試和驗證自動駕駛車輛和機器人&#xff0c;操作數字孿生來優化工業制造&#xff0c;并為科學發現鋪平新的道路。 如今&#xff0c;3D 設計和世界構建仍然是高度…

C#的 Settings.Settings配置文件的使用方法

1、定義 在Settings.settings文件中定義配置字段。把作用范圍定義為&#xff1a;User則運行時可更改(用戶范圍的字段數據更改存儲在用戶信息中&#xff0c;不在該程序文件中)&#xff0c;Applicatiion則運行時不可更改。可以使用數據網格視圖(VS軟件的Properties 下面的Setting…

常見的Redux問題

在React中使用Redux的面試題目通常涵蓋了Redux的基本概念、工作原理、如何在React應用中集成Redux等方面。以下是一些常見的Redux問題&#xff1a; Redux的核心概念&#xff1a; 1、什么是Redux&#xff1f;它解決了什么問題&#xff1f; 它是一個狀態管理庫&#xff0c;解決…

2023國賽數學建模思路 - 復盤:校園消費行為分析

文章目錄 0 賽題思路1 賽題背景2 分析目標3 數據說明4 數據預處理5 數據分析5.1 食堂就餐行為分析5.2 學生消費行為分析 建模資料 0 賽題思路 &#xff08;賽題出來以后第一時間在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 賽題背景 校園一卡通是集…

個保新標 | 《信息安全技術 敏感個人信息處理安全要求》(征求意見稿)發布

8 月 9 日&#xff0c;全國信息安全標準化技術委員會公開發布關于國家標準《信息安全技術 敏感個人信息處理安全要求》&#xff08;征求意見稿&#xff09;&#xff08;以下簡稱《標準》&#xff09;的通知&#xff0c;面向社會廣泛征求意見。 《標準》的制定背景是為支撐《個人…

《Go 語言第一課》課程學習筆記(一)

配好環境&#xff1a;選擇一種最適合你的 Go 安裝方法 選擇 Go 版本 一般情況下&#xff0c;建議采用最新版本。因為 Go 團隊發布的 Go 語言穩定版本的平均質量一直是很高的&#xff0c;少有影響使用的重大 bug。可以根據不同實際項目需要或開源社區的情況使用不同的版本。 有…

攻擊LNMP架構Web應用

環境配置(centos7) 1.php56 php56-fpm //配置epel yum install epel-release rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm//安裝php56&#xff0c;php56-fpm及其依賴 yum --enablereporemi install php56-php yum --enablereporemi install php…

常見的字符編碼有哪些?有什么區別?

目錄 面試回答 知識擴展 Unicode 和 UTF-8 有啥關系&#xff1f; 有了 UTF-8&#xff0c;為什么要出現 GBK 為什么會出現亂碼 面試回答 就像電報只能發出“滴”和“答”聲一樣&#xff0c;計算機只認為 0 和1 兩種字符&#xff0c;但是&#xff0c;人類的文字是多種多樣的&…

B樹和B+樹區別

B樹和B樹的區別 B樹 B樹被稱為平衡樹&#xff0c;在B樹中&#xff0c;一個節點可以有兩個以上的子節點。B樹的高度為log M N。在B樹中&#xff0c;數據按照特定的順序排序&#xff0c;最小值在左側&#xff0c;最大值在右側。 B樹是一種平衡的多分樹&#xff0c;通常我們說m階…

什么是網絡地址轉換 (NAT)

網絡地址轉換&#xff08;NAT&#xff09;是更改源和目標 IP 地址和端口的過程&#xff0c;地址轉換減少了對 IPv4 公共地址的需求&#xff0c;并隱藏了專用網絡地址范圍&#xff0c;該過程通常由路由器或防火墻完成。 NAT是如何工作的 NAT 允許單個設備&#xff08;如路由器…

rhel 8.7 部署 keepalived+haproxy 實現 mysql 雙主高可用場景

文章目錄 [toc]部署 mysql關閉防火墻關閉 selinux創建相關目錄創建 mysql 用戶配置 PATH 變量驗證 mysql 命令切換到 mysql 用戶在 172.72.0.116 生成配置文件在 172.72.0.137 生成配置文件mysql 初始化啟動 mysql 服務修改 mysql 的 root 用戶密碼配置主從關系172.72.0.137 配…

數字化格局下的引領者:百望云通過強制性國家標準GB18030-2022最高級別認證

8月1日,強制性國家標準GB 18030-2022《信息技術 中文編碼字符集》實施。8月15日,百望云“綠頁閱讀器”正式通過中國電子技術標準化研究院強制性國家標準GB18030-2022《信息技術 中文編碼字符集》最高級(實現級別3)認證,彰顯了百望云在數字化信息處理領域對標國家標準的卓越技術…

Android CameraX適配Android13的踩坑之路

AndroidCameraX適配Android13的踩坑之路 前言&#xff1a; 最近把AGP插件升級到8.1.0&#xff0c;新建項目的時候目標版本和編譯版本都是33&#xff0c;發現之前的demo使用Camerax拍照和錄像都失敗了&#xff0c;于是查看了一下官網和各種資料&#xff0c;找到了Android13的適…

網絡編程(12): TCP重傳、滑動窗口、流量控制、擁塞控制

1、TCP重傳機制 通過序列號和確認號確保可靠傳輸&#xff0c;當發送端發送數據給接收到&#xff0c;接收端會返回一個確認號&#xff0c;表示收到消息了 超時重傳&#xff1a;沒有在指定時間內收到ACK報文 超時重傳的兩種可能&#xff1a;數據包丟失、確認包丟失超時重傳時間RT…

第十三課:QtCmd 命令行終端應用程序開發

功能描述&#xff1a;開發一個類似于 Windows 命令行提示符或 Linux 命令行終端的應用程序 一、最終演示效果 QtCmd 不是因為它是 Qt 的組件&#xff0c;而是采用 Qt 開發了一個類似 Windows 命令提示符或者 Linux 命令行終端的應用程序&#xff0c;故取名為 QtCmd。 上述演示…

FreeMarker系列--list的用法(長度,遍歷,下標,嵌套,排序)

原文網址&#xff1a;FreeMarker系列--list的用法&#xff08;長度,遍歷,下標,嵌套,排序&#xff09;_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹FreeMarker的list的用法。 大小 Java ArrayList<String> list new ArrayList<String>(); Freemaker ${list?s…