C/C++ 入門(10)list類(STL)

個人主頁:仍有未知等待探索-CSDN博客

專題分欄:C++

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 歡迎來指教!

目錄

一、標準庫中的list

1、了解

2、常用接口說明

a.常見的構造函數

?b.迭代器

c. Capacity?編輯

d.Element access

e.Modifiers

二、實現

1、框架?

a.節點

b.迭代器

c.鏈表

2、節點

3、迭代器?

?4、鏈表

三、反向迭代器

四、問題

1、迭代器中的箭頭操作符為什么返回的是地址?


一、標準庫中的list

1、了解

list:是一個雙向帶頭循環鏈表,不支持隨機訪問(即下標訪問),任意位置的插入刪除效率高。

2、常用接口說明

a.常見的構造函數

list的構造函數
構造函數接口說明
list(size_t n, const T& val = t())構造n個值為val的list
list()構造空的list

list(const list& x)

拷貝構造
list(iterator first, iterator second)用[first, second)構造list

?b.迭代器

迭代器可以看作是一個指向節點的指針。

(rbegin和rend是反向迭代器,rbegin是指向了鏈表的尾部,rend是指向了鏈表的頭部)

注意:

?begin,進行++操作是往后面走。

rbegin,進行++操作是往前面走。

c. Capacity

d.Element access

e.Modifiers

二、實現

?老規矩,我們還是先對結構進行分析。?

鏈表:除了一些對鏈表的基本操作之外,還需要有迭代器和節點。

1、框架?

#include <cstring>
#include <iostream>
using namespace std;// 開辟一個自己的命名空間
namespace my
{// 鏈表節點// 迭代器// 鏈表
}

a.節點

// 鏈表節點
template<class T>
struct ListNode
{ListNode<T>* _prev;ListNode<T>* _next;T val;// 缺省參數,如果沒有傳參的話,默認是T類型的無參構造// 這樣做是為了防止T是一個自定義類型ListNode(const T& e = T()):_prev(nullptr),_next(nullptr),val(e){}
};

b.迭代器

其實這樣的迭代器是不完整的,我們在后面會對其進行擴展。

template<class T>
struct NodeIterator
{// 對于節點和迭代器的重命名,方便書寫typedef ListNode<T> Node;// 節點	typedef NodeIterator<T> Self; // 迭代器Node* _node;// 迭代器是用節點的指針來進行構造的NodeIterator(Node* node):_node(node){}
};

c.鏈表

// 鏈表
// list是一個帶頭雙向循環鏈表
template<class T>
class list
{typedef ListNode<T> Node;// 節點
public:typedef NodeIterator<T, T&, T*> iterator;// 迭代器
private:Node* _head;// 鏈表的頭部size_t _size;// 鏈表的長度
};

2、節點

其實節點這部分沒有什么可以講解的。唯一一個要理解的就是這個(const T& e = T())。

//const T& e = T()
// 首先T()是一個匿名對象的寫法
// 為什么我們需要用到一個匿名對象,而不是一個const T& e = 值?
// 1、我們不知道T是什么類型,不知道值可以設成一個什么類型的值
// 2、如果我們設置成一個內置類型,而T是一個自定義類型的話,類型不匹配
ListNode(const T& e = T()):_prev(nullptr),_next(nullptr),val(e){}

3、迭代器?

?我之前框架里所寫的就是老版本的迭代器。

新版本里面的迭代器主要添加了兩個新的模板變量(Ref,Ptr),引入的這兩個變量是對解引用和引用的重寫。

思考題:怎么寫const版本的迭代器呢?

答:新版本寫法的迭代器可以直接這么寫(以int為例):

NodeIterator<int, const int&, const int*>

思考題:反向迭代器怎么實現的?

標準庫里面的begin()和end() 與 rbegin()和rend()采用的是對稱法。

// 迭代器
// 新版本
// 鏈表迭代器:模仿指針的行為
// Ref:引用,Ptr指針
template<class T, class Ref, class Ptr>
struct NodeIterator
{typedef ListNode<T> Node;// 節點	typedef NodeIterator<T, Ref, Ptr> Self; // 迭代器Node* _node;NodeIterator(Node* node):_node(node){}// 前置++Self& operator++(){_node = _node->_next;return *this;   }// 后置++Self& operator++(int){Self tmp(*this);_node = _node->_next;return tmp; }// 前置--Self& operator--(){_node = _node->_prev;return *this;}// 后置--Self& operator--(int){Self tmp(_node);_node = _node->_prev;return tmp;}// 解引用Ref operator*(){return _node->val;}// -> Ptr operator->(){return &_node->val;}// ==bool operator==(const Self& s){return _node == s._node;}// !=bool operator!=(const Self& s){return !(*this == s); }
};老版本:缺點:無法實現const的迭代器鏈表迭代器:模仿指針的行為
//template<class T>
//struct NodeIterator
//{
//	typedef ListNode<T> Node;// 節點
//	typedef NodeIterator<T> Self; // 迭代器
//
//	Node* _node;
//
//	NodeIterator(Node* node)
//		:_node(node)
//	{}
//	// 前置++
//	Self& operator++()
//	{
//		_node = _node->_next;
//		return *this;   
//	}
//	// 后置++
//	Self& operator++(int)
//	{
//		Self tmp(*this);
//		_node = _node->_next;
//		return tmp; 
//	}
//	// 前置--
//	Self& operator--()
//	{
//		_node = _node->_prev;
//		return *this;
//	}
//	// 后置--
//	Self& operator--(int)
//	{
//		Self tmp(_node);
//		_node = _node->_prev;
//		return tmp;
//	}
//	// 解引用
//	T& operator*()
//	{
//		return _node->val;
//	}
//	// ==
//	bool operator==(const Self& s)
//	{
//		return _node == s._node;
//	}
//	// !=
//	bool operator!=(const Self& s)
//	{
//		return !(*this == s); 
//	}
//
//	// -> 
//	T* operator->()
//	{
//		return &_node->val;
//	}
//};
// 反向迭代器
template<class Iterator, class Ref, class Ptr>
struct Reverse_iterator
{typedef Reverse_iterator<Iterator, Ref, Ptr> Self;Iterator _it;Reverse_iterator(Iterator it):_it(it){}Ref operator*(){Iterator tmp(_it);return *( -- tmp);}Ptr operator->(){//return &_it.operator->();return &(_it.operator*());}Self& operator++(){_it -- ;return *this;}Self& operator--(){_it ++;return *this;}bool operator!=(const Self& s){return _it != s._it;}
};

?4、鏈表

// 鏈表
template<class T>
class list
{typedef ListNode<T> Node;
public:typedef NodeIterator<T, T&, T*> iterator;typedef NodeIterator<T, const T&, const T*> const_iterator;// 構造函數list ():_size(0){_head = new Node;_head -> _next = _head;_head -> _prev = _head;}list (size_t n, const T& val = T()):_size(0){_head = new Node;_head -> _next = _head;_head -> _prev = _head;for (size_t i = 0; i < n; i ++ ){push_back(val);}}list (list<T>& x):_size(0){_head = new Node;_head -> _next = _head;_head -> _prev = _head;iterator it = x.begin();while (it != x.end()){push_back(*it);it ++ ;}}list (iterator first, iterator last):_size(0){_head = new Node;_head -> _next = _head;_head -> _prev = _head;iterator it = first;while (it != last){insert(end(), *it);it ++ ;}}~list(){clear();delete _head;_head = nullptr;}// 訪問// const版本的迭代器,迭代器的指向的內容不能被修改// 1、自己單獨實現一個const版本的迭代器// 2、將const和非const合成一個,通過模板參數進行控制const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}iterator begin(){return iterator(_head->_next);}iterator end(){return iterator(_head);}// list capacitybool empty(){return _size == 0;}size_t size(){return _size;}// list element accessT& front(){return *begin();}T& back(){return *end();}// list modifiers/*void push_back(const T& val){Node* tmp = new Node;tmp -> val = val;Node* tail = _head -> _prev;tmp->_next = tail->_next;tail->_next = tmp;tmp->_prev = tail;_head->_prev = tmp;_size ++ ;}*/void push_back(const T& val){insert(end(), val);}void push_front(const T& val){insert(begin(), val);}iterator insert (iterator position, const T& val){Node* tmp = new Node(val);tmp->_next = position._node;tmp->_prev = position._node->_prev;position._node->_prev->_next = tmp;position._node->_prev = tmp;_size ++ ;return iterator(tmp);}void pop_back(){erase( -- end());}void pop_front(){erase(begin());}iterator erase (iterator position){iterator tmp(position._node->_next);position._node->_prev->_next = position._node->_next;position._node->_next->_prev = position._node->_prev;delete position._node;_size -- ;return tmp;}void clear(){while (_size){erase(begin());}}void swap(list& l){std::swap(_head, l._head);std::swap(_size, l._size);}private:Node* _head;size_t _size;
};

三、反向迭代器

通過前面例子知道,反向迭代器的++就是正向迭代器的--,反向迭代器的--就是正向迭代器的++,因此反向迭代器的實現可以借助正向迭代器,即:反向迭代器內部可以包含一個正向迭代器,對正向迭代器的接口進行包裝即可。

四、問題

1、迭代器中的箭頭操作符為什么返回的是地址?

?答:其實是編譯器省略了一個箭頭,例如:Iterator it;

正常的調用是:it.operator->()->val; 省略了一個箭頭是為了提高代碼的可讀性。

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

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

相關文章

簡單易懂的Java Queue入門教程!

哈嘍&#xff0c;各位小伙伴們&#xff0c;你們好呀&#xff0c;我是喵手。運營社區&#xff1a;C站/掘金/騰訊云&#xff1b;歡迎大家常來逛逛 今天我要給大家分享一些自己日常學習到的一些知識點&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相學習&#xff0c;一…

如何建設智慧黨校

隨著信息技術的飛速展開&#xff0c;特別是近年移動互聯網技術&#xff0c;物聯網技術&#xff0c;人工智能技術&#xff0c;大數據數據的深入展開&#xff0c;我國快速的進入信息化社會&#xff0c;信息化對各行各業的改造越來越深入&#xff0c;任何職業&#xff0c;任何安排…

SSM【Spring SpringMVC Mybatis】—— Spring(一)

目錄 1、初識Spring 1.1 Spring簡介 1.2 搭建Spring框架步驟 1.3 Spring特性 1.5 bean標簽詳解 2、SpringIOC底層實現 2.1 BeanFactory與ApplicationContexet 2.2 圖解IOC類的結構 3、Spring依賴注入數值問題【重點】 3.1 字面量數值 3.2 CDATA區 3.3 外部已聲明be…

淺談ArrayList和LinkedList的區別

ArrayList和LinkedList在Java中都是常用的List接口的實現類&#xff0c;但它們之間存在一些顯著的區別。 實現方式&#xff1a; ArrayList&#xff1a;基于數組實現。內部使用一個動態數組來存儲元素&#xff0c;這意味著可以通過索引快速訪問元素&#xff0c;時間復雜度為O(1)…

算法學習筆記(Nim游戲)

N i m Nim Nim游戲 n n n堆物品&#xff0c;每堆有 a i a_i ai?個&#xff0c;每個玩家輪流取走任意一堆的任意個物品&#xff0c;但不能不取&#xff0c;取走最后一個物品的人獲勝。 N i m Nim Nim游戲是一種經典的公平組合游戲。現在對它進行分析。 首先定義兩個博弈中的狀…

【Chisel】chisel中怎么處理類似verilog的可變位寬和parameter

在 Chisel 中處理可變位寬和參數的方式與 Verilog 有一些不同&#xff0c;因為 Chisel 是建立在 Scala 語言之上的。以下是如何在 Chisel 中處理這些概念的方法&#xff1a; 參數化&#xff08;Parameters&#xff09; 在 Chisel 中&#xff0c;參數化是通過在模塊構造函數中定…

VUE使用餓了么的上傳組件時實現圖片預覽

創作靈感 最近在寫項目時&#xff0c;遇到了上傳頭像的需求&#xff0c;我使用的是element組件中的upload組件。但是在使用時&#xff0c;我需要實現預覽、手動上傳頭像等功能。然而在使用餓了么組件時&#xff0c;這些功能還是需要我們自己去手動實現的&#xff0c;在手動實現…

Linux makefile進度條

語法 在依賴方法前面加上就不會顯示這一行的命令 注意 1.make 會在當前目錄下找名為“makefile” 或者 “Makefile” 的文件 2.為了生成第一依賴文件&#xff0c;如果依賴文件列表有文件不存在&#xff0c;則會到下面的依賴關系中查找 3..PHONY修飾的依賴文件總是被執行的 …

Redis——RDB、AOF和混合持久化機制

Redis提供了三種持久化機制來確保數據的持久保存&#xff0c;分別是RDB&#xff08;Redis DataBase&#xff09;、AOF&#xff08;Append Only File&#xff09;和混合持久化。 RDB&#xff08;Redis DataBase&#xff09; RDB持久化機制是將Redis在內存中的數據保存到磁盤上的…

xss-lab 1-18關payload

Less-1 ?name<script>alert()</script> Less-2 "><script>alert()</script> "οnclick"alert() " οnfοcus"alert() " οnblur"alert() Less-3 οnfοcusalert() οnbluralert() οnfοcusjavascript:aler…

Spring AopUtils深度解析:從入門到精通的全方位指南

1. 概述 AopUtils是Spring框架中的一個工具類&#xff0c;主要用于處理AOP&#xff08;面向切面編程&#xff09;相關的操作。它提供了一系列靜態方法&#xff0c;幫助開發者更方便地處理AOP中的對象、代理以及通知&#xff08;Advice&#xff09;等。 2. 用途 AopUtils的主要…

操作系統原理與系統——實驗十三多道批處理作業調度(作業可移動)

關鍵代碼 #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct data{int hour;//當前小時int min;//當前分鐘 }time; struct node{char name[20];//進程名time arrive;//到達就緒隊列時間int zx;//執行時間(預期時間)int size;int ta…

Polygon市值機器人

隨著區塊鏈技術的蓬勃發展和數字貨幣市場的日益繁榮&#xff0c;投資者們對于如何精準把握市場動態、實現資產穩健增長的需求愈發迫切。在這個背景下&#xff08;市值管理飛//機//aishutuyu&#xff09;&#xff0c;Polygon市值機器人應運而生&#xff0c;作為一款基于Polygon公…

LeetCode 第397場周賽個人題解

目錄 100296. 兩個字符串的排列差 原題鏈接 思路分析 AC代碼 100274. 從魔法師身上吸取的最大能量 原題鏈接 思路分析 AC代碼 100281. 矩陣中的最大得分 原題鏈接 思路分析 AC代碼 100312. 找出分數最低的排列 原題鏈接 思路分析 AC代碼 100296. 兩個字符串的排…

timerfd加epoll封裝定時器

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 1、用timerfd加epoll封裝定時器的優點2、代碼實現 1、用timerfd加epoll封裝定時器的優點 定時器為什么需要timerfd 在設計定時器時&#xff0c;我們首先想到的就是…

【SpringBoot】Redis Lua腳本實戰指南:簡單高效的構建分布式多命令原子操作、分布式鎖

文章目錄 一.Lua腳本1.Lua特性2.Lua優勢 二.Lua語法1.注釋2.變量3.數據類型&#xff1a;3.1.基本類型3.2.對象類型&#xff1a;表&#xff08;table&#xff09; 4.控制結構&#xff1a;4.1.條件語句: 使用if、else和elseif來實現條件分支。4.2.循環結構&#xff1a;Lua支持for…

Shell參數擴展形式學習筆記

Shell參數擴展形式學習筆記 文章目錄 Shell參數擴展形式學習筆記空值判斷處理 ${parameter:-word} ${parameter:word} ${parameter:?word} ${parameter:word}變量位置截取 ${parameter:offset} ${parameter:offset:length}變量匹配組合 ${!prefix*} ${!prefix} ${!name[]} ${!…

感知機和神經網絡

引入 什么是神經網絡&#xff1f; 我們今天學習的神經網絡&#xff0c;不是人或動物的神經網絡&#xff0c;但是又是模仿人和動物的神經網絡而定制的神經系統&#xff0c;特別是大腦和神經中樞&#xff0c;定制的系統是一種數學模型或計算機模型&#xff0c;神經網絡由大量的人…

圖像處理:圖像噪聲添加

文章目錄 前言一、高斯噪聲二、椒鹽噪聲三、泊松噪聲四、斑點噪聲五、指數噪聲六、均勻噪聲總結 前言 本文主要介紹幾種添加圖像噪聲的方法&#xff0c;用于數據增強等操作。 以下圖為例。 一、高斯噪聲 高斯噪聲就是給圖片添加一個服從高斯分布的噪聲&#xff0c;可以通過調…

vLLM初探

vLLM是伯克利大學LMSYS組織開源的大語言模型高速推理框架&#xff0c;旨在極大地提升實時場景下的語言模型服務的吞吐與內存使用效率。vLLM是一個快速且易于使用的庫&#xff0c;用于 LLM 推理和服務&#xff0c;可以和HuggingFace 無縫集成。vLLM利用了全新的注意力算法「Page…