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

詳解C++?STL模擬實(shí)現(xiàn)list

 更新時(shí)間:2023年01月11日 10:59:44   作者:叫我小秦就好了  
這篇文章主要為大家詳細(xì)介紹了C++如何模擬實(shí)現(xiàn)STL容器list,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下

list 概述

相比于 vector 的連續(xù)線性空間,list 采用的是零散的空間,它的好處是每次插入或刪除一個(gè)元素,就配置或釋放一個(gè)元素空間。

list 是支持常數(shù)時(shí)間從容器任何位置插入和移除元素容器,但不支持快速隨機(jī)訪問(wèn)。list 通常實(shí)現(xiàn)為雙向鏈表,與 forward_list 相比,list 的迭代器可以向前移動(dòng),但也因此需要在節(jié)點(diǎn)中多開(kāi)辟一個(gè)指針變量,在空間上效率稍低。

接口總覽

namespace qgw {
	/// @brief list 中每個(gè)節(jié)點(diǎn)
	/// @tparam T 節(jié)點(diǎn)存儲(chǔ)的數(shù)據(jù)的類(lèi)型
	template <class T>
	struct _list_node {
		_list_node(const T& data = val());	// 節(jié)點(diǎn)類(lèi)的構(gòu)造函數(shù)

		_list_node<T>* _prev;				// 指向前一節(jié)點(diǎn)
		_list_node<T>* _next;				// 指向后一節(jié)點(diǎn)
		T _data;							// 存儲(chǔ)節(jié)點(diǎn)數(shù)據(jù)
	};

	/// @brief list 的迭代器
	/// @tparam T list 數(shù)據(jù)的類(lèi)型
	/// @tparam Ref 數(shù)據(jù)的引用類(lèi)型
	/// @tparam Ptr 數(shù)據(jù)的指針類(lèi)型
	template <class T, class Ref, class Ptr>
	struct _list_iterator {
		typedef _list_iterator<T, T&, T*>		iterator;
		typedef _list_iterator<T, Ref, Ptr>		self;

		typedef T		value_type;
		typedef Ptr		pointer;
		typedef Ref		reference;
		typedef _list_node<T> list_node;
		
        // 構(gòu)造函數(shù)
        _list_iterator(list_node* node = nullptr);
        
		// 各種運(yùn)算符重載
		bool operator==(const self& x) const;
		bool operator!=(const self& x) const;
		reference operator*() const;
		pointer operator->() const;
		self& operator++();
		self operator++(int);
		self& operator--();
		self operator++(int);

		list_node* _node;	// 指向?qū)?yīng)的 list 節(jié)點(diǎn)
	};

	template <class T>
	class list {
	public:
		typedef T value_type;
		typedef T* pointer;
		typedef T& reference;
		typedef _list_node<T>	list_node;
		typedef _list_iterator<T, T&, T*>             iterator;
		typedef _list_iterator<T, const T&, const T*> const_iterator;

	public:
		// 默認(rèn)成員函數(shù)
		list();
		list(const list<T>& other);
		list<T>& operator=(const list<T>& other);
		~list();

		// 元素訪問(wèn)
		reference front();
		reference back();

		// 迭代器
		iterator begin();
		iterator end();
		const_iterator begin() const;
		const_iterator end() const;

		// 容量
		bool empty() const;
		size_t size() const;

		// 修改器
		void clear();
		iterator insert(iterator pos, const T& val);
		void push_front(const T& val);
		void push_back(const T& val);
		iterator erase(iterator pos);
		void pop_front();
		void pop_back();
		void swap(list& other);

		// 操作
		void splice(iterator pos, list& other);
		void splice(iterator pos, list& other, iterator it);
        void splice(iterator pos, list& other, iterator first, iterator last);
		void merge(list& other);
		void remove(const T& value);
		void reverse();
		void unique();

	private:
		list_node* _node;	// 指向鏈表頭節(jié)點(diǎn)
	};
}

list 的節(jié)點(diǎn)

list 的節(jié)點(diǎn)我們?cè)O(shè)計(jì)成一個(gè) _list_node 類(lèi),里面有三個(gè)成員變量,分別為前后指針和數(shù)據(jù)。

它的構(gòu)造函數(shù)將數(shù)據(jù)初始化為給定數(shù)據(jù),再將前后指針初始化為空即可。

/// @brief 節(jié)點(diǎn)類(lèi)的構(gòu)造函數(shù)
/// @param data 用來(lái)構(gòu)造節(jié)點(diǎn)的初值
_list_node(const T& data = T()) 
    : _data(data) {
        _prev = nullptr;
        _next = nullptr;
    }

默認(rèn)成員函數(shù)

默認(rèn)構(gòu)造函數(shù)

SGI list 不僅是一個(gè)雙向鏈表,還是一個(gè)帶頭的循環(huán)鏈表。

/// @brief 構(gòu)造一個(gè)空鏈表
list() {
    _node = new list_node;    // 創(chuàng)建一個(gè)頭節(jié)點(diǎn)
    _node->_prev = _node;    // 前面指向自己
    _node->_next = _node;    // 后面指向自己
}

析構(gòu)函數(shù)

list 的析構(gòu)函數(shù),先調(diào)用 clear 釋放數(shù)據(jù)資源,再 delete 掉頭節(jié)點(diǎn)即可。

/// @brief 釋放資源
~list() {
    clear();
    delete _node;
    _node = nullptr;
}

拷貝構(gòu)造函數(shù)

用另一容器創(chuàng)建新對(duì)象。

先申請(qǐng)一個(gè)頭節(jié)點(diǎn),然后遍歷 other 容器,將 other 中的數(shù)據(jù)逐一尾插到 *this 中。

/// @brief 用給定容器初始化
/// @param other 用來(lái)初始化的容器
list(const list<T>& other) {
    _node = new list_node; 
    _node->_next = _node;
    _node->_prev = _node;
    for (const auto& e : other) {
        push_back(e); 
    }
}

復(fù)制賦值函數(shù)

先創(chuàng)建給定容器的拷貝 tmp,然后交換 *this 和 tmp,最后返回 *this。

/// @brief 替換容器內(nèi)容
/// @param other 用作數(shù)據(jù)源的另一容器
/// @return *this
list<T>& operator=(const list<T>& other) {
    // tmp 出了作用域就銷(xiāo)毀了
    list<T> tmp(other);
    swap(tmp);
    // 返回引用可以連續(xù)賦值
    return *this;
}

list 的迭代器

list 的節(jié)點(diǎn)在內(nèi)存中不是連續(xù)存儲(chǔ)的,因此不能使用原生指針作為 list 的迭代器。list 的迭代器必須有能力指向 list 的節(jié)點(diǎn),并能夠正確的遞增、遞減、取值、成員存取等操作。正確的操作是指:遞增時(shí)指向下一節(jié)點(diǎn),遞減時(shí)指向上一節(jié)點(diǎn),取值時(shí)取的是節(jié)點(diǎn)的數(shù)據(jù)值,成員取用的是節(jié)點(diǎn)的成員。

由于 STL list 是一個(gè)雙向鏈表(double linked-list),迭代器必須具備前移、后移的能力,所以 list 提供的是 Bidirectional Iterators。

構(gòu)造函數(shù)

list 的迭代器中成員變量只有一個(gè)節(jié)點(diǎn)指針,將其指向給定節(jié)點(diǎn)即可。

/// @brief list 迭代器的構(gòu)造函數(shù)
/// @param node 用來(lái)構(gòu)造的節(jié)點(diǎn)
_list_iterator(list_node* node = nullptr) {
    _node = node;
}

operator==

判斷兩迭代器指向的節(jié)點(diǎn)是否為同一個(gè),直接比較迭代器中節(jié)點(diǎn)的指針即可。切記不能比較指針中的值,因?yàn)椴煌?jié)點(diǎn)的值可能相同。

/// @brief 判斷兩迭代器指向的節(jié)點(diǎn)是否相同
/// @param x 用來(lái)比較的迭代器
/// @return 相同返回 true,不同返回 false
bool operator==(const self& x) const {
    return _node == x._node;
}

operator!=

!= 的比較方法和 == 一樣。

/// @brief 判斷兩迭代器指向的節(jié)點(diǎn)是否不同
/// @param x 用來(lái)比較的迭代器
/// @return 不同返回 true,相同返回 false
bool operator!=(const self& x) const {
    return _node != x._node;
}

operator*

迭代器是模仿指針的,讓我們可以像使用指針一樣。因此可以對(duì)迭代器進(jìn)行解引用操作,該操作得到的是迭代器中節(jié)點(diǎn)指針指向的數(shù)據(jù),并且返回引用,因?yàn)橛锌赡苄薷脑摂?shù)據(jù)。

/// @brief 獲取指向節(jié)點(diǎn)中的數(shù)據(jù)值
/// @return 返回指向節(jié)點(diǎn)數(shù)據(jù)的引用
reference operator*() const {
    return _node->_data;
}

operator->

-> 運(yùn)算符的重載稍顯復(fù)雜,讓我們先看下面這個(gè)場(chǎng)景。

也就是 list 中存儲(chǔ)的是自定義類(lèi)型,自定義類(lèi)型中又有多個(gè)成員變量,我們想取出指定的成員變量,當(dāng)然這里用 . 也可以做到。

// 有一個(gè)學(xué)生類(lèi),里面有姓名和學(xué)號(hào)兩個(gè)成員
struct Stu {
	string name;
    string id;
};

list<Stu> s;
Stu s1 = { "qgw", "001" };
Stu s2 = { "wlr", "002" };
s.push_back(s1);
s.push_back(s2);
list<Stu>::iterator ptr = s.begin();
// 輸出第一個(gè)學(xué)生的姓名和學(xué)號(hào)
cout << (*ptr).name << endl;
cout << s.begin()->id << endl;
/// @brief 獲取節(jié)點(diǎn)中數(shù)據(jù)的地址
/// @return 返回節(jié)點(diǎn)指向的數(shù)據(jù)的地址
pointer operator->() const {
    return &(operator*());
}

看到這你可能會(huì)疑惑,operator-> 返回的是節(jié)點(diǎn)的數(shù)據(jù)的地址,也是說(shuō)上面 s.begin()-> 得到的是一個(gè)地址,那這條語(yǔ)句是怎么執(zhí)行的?

實(shí)際上這里確實(shí)應(yīng)該有兩個(gè)箭頭像這樣 s.begin()->->id,但這種方式的可讀性太差了,所以編譯器對(duì)此做了優(yōu)化,在編譯為我們添加一個(gè)箭頭。

operator++

operator++ 運(yùn)算符的作用十分清晰,就是讓迭代器指向鏈表中下一節(jié)點(diǎn)。

前置實(shí)現(xiàn)的思路是:通過(guò)迭代器中的節(jié)點(diǎn)指針找到下一節(jié)點(diǎn),然后賦值給迭代器中的節(jié)點(diǎn)指針。

后置實(shí)現(xiàn)的思路是:先保存當(dāng)前位置迭代器,然后調(diào)用前置 ++,最后返回臨時(shí)變量。

需要注意的是:前置 ++ 返回的是前進(jìn)后迭代器的引用,后置 ++ 返回的是一個(gè)臨時(shí)變量。

/// @brief 前置++
/// @return 返回前進(jìn)一步后的迭代器
self& operator++() {
    _node = _node->_next;
    return *this;
}

/// @brief 后置++
/// @param  無(wú)作用,只是為了與前置 ++ 進(jìn)行區(qū)分,形成重載
/// @return 返回當(dāng)前的迭代器
self operator++(int) {
    self tmp = *this;
    // 直接調(diào)用前置 ++
    ++(*this);
    return tmp;
}

operator--

前置實(shí)現(xiàn)的思路是:通過(guò)迭代器中的節(jié)點(diǎn)指針找到前一節(jié)點(diǎn),然后賦值給迭代器中的節(jié)點(diǎn)指針。

后置實(shí)現(xiàn)的思路是:先保存當(dāng)前位置迭代器,然后調(diào)用前置 --,最后返回臨時(shí)變量。

/// @brief 前置 --
/// @return 返回后退一步后的迭代器
self& operator--() {
    _node = _node->_prev;
    return *this;
}

/// @brief 后置 --
/// @param  無(wú)作用,只是為了與前置 -- 進(jìn)行區(qū)分,形成重載
/// @return 返回當(dāng)前的迭代器
self operator--(int) {
    self tmp = *this;
    --(*this);
    return tmp;
}

元素訪問(wèn)

front

front 獲取第一個(gè)元素的引用,直接用 begin 獲取指向第一個(gè)元素的迭代器,再解引用即可。

/// @brief 返回容器首元素的引用
/// @return 首元素的引用
reference front() {
    return *begin();
}    

back

end 獲取最后一個(gè)元素的引用,先用 end 獲取最后一個(gè)元素下一位置的迭代器,再回退一步,然后解引用就可以了。

/// @brief 返回容器中最后一個(gè)元素的引用
/// @return 最后元素的引用
reference back() {
    return *(--end());
}

迭代器

在 begin 和 end 實(shí)現(xiàn)之前,我們先來(lái)看下 list 的示意圖,下圖為有 3 個(gè)元素的鏈表:

begin

begin 獲取的是首元素的迭代器,根據(jù)上圖,begin 的實(shí)現(xiàn)也就非常清晰了,直接返回頭節(jié)點(diǎn)的下一位置即可。

/// @brief 返回指向 list 首元素的迭代器
/// @return 指向首元素的迭代器
iterator begin() {
    // 根據(jù)節(jié)點(diǎn)指針構(gòu)造迭代器
    return iterator(_node->_next);
}

// const 版本供 const 容器使用
const_iterator begin() const {
    return const_iterator(_node->_next);
}

end

end 獲取的是最后一個(gè)元素下一個(gè)位置的迭代器,根據(jù)上圖就是 _node 所指向的節(jié)點(diǎn)。

/// @brief 返回指向 list 末元素后一元素的迭代器
/// @return 指向最后元素下一位置的迭代器
iterator end() {
    // 調(diào)用 iterator 構(gòu)造函數(shù)
    return iterator(_node);
}

const_iterator end() const {
    return const_iterator(_node);
}

容量

empty

begin 和 end 指向相同,說(shuō)明鏈表此時(shí)只有一個(gè)頭節(jié)點(diǎn),鏈表為空。

/// @brief 檢查容器是否無(wú)元素
/// @return 若容器為空則為 true,否則為 false
bool empty() const {
    return begin() == end();
}

size

size 函數(shù)的作用是返回容器中元素的數(shù)量。

在 C++ 11 前,該函數(shù)的復(fù)雜度可能是常數(shù)的,也可能是線性的。從 C++ 11 起該函數(shù)的復(fù)雜度為常數(shù)。

下面代碼的時(shí)間復(fù)雜度是線性的,要想改成常數(shù)也很簡(jiǎn)單,只需要在 list 中開(kāi)辟一個(gè)成員變量記錄個(gè)數(shù)即可。

/// @brief 返回容器中的元素?cái)?shù)
/// @return 容器中的元素?cái)?shù)量
size_t size() const {
    size_t sz = 0;
    auto it = begin();
    while (it != end()) {
        ++it;
        ++sz;
    }
    return sz;
}

修改器

insert

下圖為:只有 0、1 兩個(gè)元素的鏈表,在 1 之前插入元素值為 2 的節(jié)點(diǎn)的示意圖。

插入的思路比較清晰:

1.插入節(jié)點(diǎn)的 _next 指向 pos 位置的節(jié)點(diǎn)

2.插入節(jié)點(diǎn)的 _prev 指向 pos 前一位置的節(jié)點(diǎn)

3.pos 前一位置的節(jié)點(diǎn)的 _next 指向插入的節(jié)點(diǎn)

4.pos 位置節(jié)點(diǎn)的 _prev 指向插入的節(jié)點(diǎn)

/// @brief 插入元素到容器中的指定位置
/// @param pos     將內(nèi)容插入到 pos 之前
/// @param val 要插入的元素值
/// @return 指向被 插入 val 的迭代器
iterator insert(iterator pos, const T& val) {
    list_node* tmp = new list_node(val);    // 創(chuàng)建要插入的節(jié)點(diǎn)
    tmp->_next = pos._node;                    // (1)
    tmp->_prev = pos._node->_prev;            // (2)
    (pos._node->_prev)->_next = tmp;        // (3)
    pos._node->_prev = tmp;                    // (4)
    return tmp;
}

push_front

push_front 的作用是在第一個(gè)元素之前插入一個(gè)節(jié)點(diǎn),直接調(diào)用 insert 在 begin 之前插入就行。

/// @brief 添加給定元素 val 到容器起始
/// @param val 要添加的元素值
void push_front(const T& val) {
    insert(begin(), val);
}

push_back

push_back 的作用是在容器的最后添加一個(gè)節(jié)點(diǎn),直接調(diào)用 insert 在 end 之前插入就行。

/// @brief 添加給定元素 val 到容器尾
/// @param val 要添加的元素值
void push_back(const T& val) {
    insert(end(), val);
}

erase

下圖為:有三個(gè)元素 0、1、2 的鏈表,刪除 pos 指向節(jié)點(diǎn)(值為 1)的示意圖。

刪除的思路也很清晰:

1.將 pos 前一節(jié)點(diǎn)的 _next 指針指向 pos 的下一節(jié)點(diǎn)

2.將 pos 下一節(jié)點(diǎn)的 _prev 指針指向 pos 的前一節(jié)點(diǎn)

3.delete 釋放掉 pos 所指向的節(jié)點(diǎn)

/// @brief 從容器擦除指定的元素
/// @param pos 指向要移除的元素的迭代器
/// @return 最后移除元素之后的迭代器
iterator erase(iterator pos) {
    list_node* nextNode = pos._node->_next;		// 記錄 pos 指向節(jié)點(diǎn)的下一節(jié)點(diǎn)
    list_node* prevNode = pos._node->_prev;		// 記錄 pos 指向節(jié)點(diǎn)的前一節(jié)點(diǎn)
    prevNode->_next = nextNode;					// (1)
    nextNode->_prev = prevNode;					// (2)
    delete (pos._node);
    return (iterator)nextNode;
}

pop_front

pop_front 移除容器第一個(gè)元素,也就是 begin 指向的節(jié)點(diǎn)。

/// @brief 移除容器首元素
void pop_front() {
    erase(begin());
}

pop_back

pop_back 移除容器最后一個(gè)節(jié)點(diǎn),也就是 end 指向的前一個(gè)節(jié)點(diǎn)。

/// @brief 移除容器的末元素
void pop_back() {
    erase(--end());
}

clear

clear 用于清空容器所有數(shù)據(jù),不清理頭節(jié)點(diǎn)。

采用遍歷的方式調(diào)用 erase 刪除每一個(gè)節(jié)點(diǎn)。

/// @brief 從容器擦除所有元素
void clear() {
    iterator it = begin();
    while (it != end()) {
        it = erase(it);
    }
}

swap

swap 用來(lái)交換兩個(gè) list 容器,不用 list 中每個(gè)元素的值,直接交換 _node 指針即可。

/// @brief 將內(nèi)容與 other 的交換
/// @param other 要與之交換內(nèi)容的容器
void swap(list& other) {
    std::swap(_node, other._node);
}

操作

splice

在實(shí)現(xiàn)該函數(shù)之前,先來(lái)看下 list 內(nèi)部的一個(gè)函數(shù) transfer。

list 內(nèi)部提供一個(gè)遷移操作(transfer):將某連續(xù)范圍的元素遷移都某個(gè)特定位置之前。

這個(gè)函數(shù)比上面所寫(xiě)的要復(fù)雜的多,要對(duì)著圖仔細(xì)思考。

/// @brief 將 [first, last) 范圍的所有元素移動(dòng)到 pos 之前
/// @param pos 將內(nèi)容移動(dòng)到 pos 之前
/// @param first 范圍起始位置
/// @param last 范圍結(jié)束位置
void transfer(iterator pos, iterator first, iterator last) {
    if (pos != last) {
        last._node->_prev->_next = pos._node;        // (1)
        first._node->_prev->_next = last._node;        // (2)
        pos._node->_prev->_next = first._node;        // (3)
        list_node* tmp = pos._node->_prev;            // (4)
        pos._node->_prev = last._node->_prev;        // (5)
        last._node->_prev = first._node->_prev;        // (6)
        first._node->_prev = tmp;                    // (7)
    }
}

有了上面的函數(shù),splice 的實(shí)現(xiàn)也就非常簡(jiǎn)單了,下面共有三個(gè)重載實(shí)現(xiàn):

根據(jù)要轉(zhuǎn)移的元素選擇調(diào)用不同的函數(shù)。

/// @brief 將 other 接合于 pos 所指位置之前,兩者不能是同一 list
/// @param pos 將內(nèi)容插入到它之前
/// @param other 要從它轉(zhuǎn)移內(nèi)容的另一容器
void splice(iterator pos, list& other) {
    if (!other.empty()) {
        transfer(pos, other.begin(), other.end());
    }
}

/// @brief 將 it 所指元素接合到 pos 所指位置之前
/// @param pos 	將內(nèi)容插入到它之前
/// @param other 要從它轉(zhuǎn)移內(nèi)容的另一容器
/// @param it 從 other 轉(zhuǎn)移到 *this 的元素
void splice(iterator pos, list& other, iterator it) {
    // 取得一個(gè) [i, j) 的范圍,使得能調(diào)用 transfer
    iterator j = it;
    ++j;
    // 檢查是否有必要執(zhí)行
    // pos == it 時(shí)說(shuō)明 pos 和 it 指向的是同一節(jié)點(diǎn)
    // pos == j 時(shí)說(shuō)明,it 剛好在 pos 之前
    if (pos == it || pos == j) {
        return;
    }
    transfer(pos, it, j);
}

/// @brief 將 [first, last) 內(nèi)的所有元素接合于 pos 所指位置之前
/// @param pos 將內(nèi)容插入到它之前
/// @param first 起始位置
/// @param last 結(jié)束位置
void splice(iterator pos, list& other, iterator first, iterator last) {
    if (first != last) {
        transfer(pos, first, last);
    }
}

merge

merge 函數(shù)和歸并排序中的合并操作類(lèi)似,該函數(shù)的作用是:合并兩個(gè)已遞增排序的鏈表。

/// @brief 合并兩個(gè)遞增鏈表,合并到 *this 上
/// @param other 要合并的另一容器
void merge(list& other) {
    iterator first1 = begin();
    iterator end1 = end();
    iterator first2 = other.begin();
    iterator end2 = other.end();

    while (first1 != end1 && first2 != end2) {
        if (*first2 < *first1) {
            iterator next = first2;
            transfer(first1, first2, ++next);
            first2 = next;
        } else {
            ++first1;
        }
    }
    if (first2 != end2) {
        // 將 other 鏈表剩余元素合并到 *this 中
        transfer(first1, first2, end2);
    }
}

remove

remove 用來(lái)刪除 list 中值等于 val 的元素,直接遍歷鏈表,找到就刪除。

/// @brief 移除等于 val 元素
/// @param val 要移除的元素的值
void remove(const T& val) {
    iterator first = begin();
    iterator last = end();
    while (first != last) {
        iterator next = first;
        ++next;
        if (*first == val) {
            erase(first);
        }
        first = next;
    }
}

reverse

reverse 的作用是逆轉(zhuǎn)容器中的元素順序。

該函數(shù)的思路簡(jiǎn)單,從第 2 個(gè)元素開(kāi)始,以次頭插到鏈表頭部。

/// @brief 將 *this 的內(nèi)容逆置
void reverse() {
    // 空鏈表或只有一個(gè)元素直接返回
    if (_node->_next == _node || _node->_next->_next == _node) {
        return;
    }

    iterator first = begin();
    ++first;
    while (first != end()) {
        iterator old = first;			// 第一次循環(huán)時(shí)指向第 2 個(gè)元素
        ++first;						// 第一次循環(huán)時(shí)指向第 3 個(gè)元素
        transfer(begin(), old, first);
    }
}

unique

unique 用來(lái)移除數(shù)值相同的連續(xù)元素,只保留一個(gè)。

該函數(shù)利用的是雙指針的思想,first 和 next 分別指向前后兩個(gè)元素,相同就刪除后一個(gè)。

/// @brief 移除數(shù)值相同的連續(xù)元素
void unique() {
    iterator first = begin();
    iterator last = end();
    if (first == last) {
        return;
    }

    iterator next = first;
    while (++next != last) {
        // 此時(shí) next 指向 first 下一個(gè)節(jié)點(diǎn)
        if (*first == *next) {
            // 連續(xù)的相同,就刪除后一個(gè)
            erase(next);
        } else {
            // 不相同 first 向 end 移動(dòng)
            first = next;
        }
        // 使 next 再次指向 first
        // 這樣再進(jìn) while 時(shí),++next 又使 next 指向 first 下一個(gè)
        next = first;
    }
}

以上就是詳解C++ STL模擬實(shí)現(xiàn)list的詳細(xì)內(nèi)容,更多關(guān)于C++ STL list的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語(yǔ)言員工業(yè)績(jī)銷(xiāo)售源代碼

    C語(yǔ)言員工業(yè)績(jī)銷(xiāo)售源代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言員工業(yè)績(jī)銷(xiāo)售源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 介紹C語(yǔ)言程序中的注釋等輔助語(yǔ)句如何使用

    介紹C語(yǔ)言程序中的注釋等輔助語(yǔ)句如何使用

    C語(yǔ)言中分為單行注釋和多行注釋?zhuān)簡(jiǎn)涡凶⑨?以?//?開(kāi)始的這一行文本,可能不被編譯器所支持;多行注釋從?/*?到?*/之間的所有文本,不支持嵌套,下面讓我們?cè)敿?xì)來(lái)了解
    2022-04-04
  • C++中與輸入相關(guān)的istream類(lèi)成員函數(shù)簡(jiǎn)介

    C++中與輸入相關(guān)的istream類(lèi)成員函數(shù)簡(jiǎn)介

    這篇文章主要介紹了C++中與輸入相關(guān)的istream類(lèi)成員函數(shù)簡(jiǎn)介,包括eof函數(shù)和peek函數(shù)以及putback函數(shù)還有ignore函數(shù),需要的朋友可以參考下
    2015-09-09
  • Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法

    Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法

    本文主要介紹了Visual Studio中scanf函數(shù)報(bào)錯(cuò)的幾種解決方法,文中通過(guò)圖文示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • VSCode配置C/C++環(huán)境的最新詳細(xì)教程

    VSCode配置C/C++環(huán)境的最新詳細(xì)教程

    VisualStudioCode(簡(jiǎn)稱(chēng)VSCode)是Microsoft開(kāi)發(fā)的代碼編輯器,它支持Windows,Linux和macOS等操作系統(tǒng)以及開(kāi)源代碼,下面這篇文章主要給大家介紹了關(guān)于VSCode配置C/C++環(huán)境的最新詳細(xì)教程,需要的朋友可以參考下
    2022-12-12
  • C++基于QWidget和QLabel實(shí)現(xiàn)圖片縮放,拉伸與拖拽

    C++基于QWidget和QLabel實(shí)現(xiàn)圖片縮放,拉伸與拖拽

    這篇文章主要為大家詳細(xì)介紹了C++如何基于QWidget和QLabel實(shí)現(xiàn)圖片縮放、拉伸與拖拽等功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • C++ 風(fēng)靡一時(shí)的連連看游戲的實(shí)現(xiàn)流程詳解

    C++ 風(fēng)靡一時(shí)的連連看游戲的實(shí)現(xiàn)流程詳解

    游戲“連連看”是源自臺(tái)灣的桌面小游戲,自從流入大陸以來(lái)風(fēng)靡一時(shí),也吸引眾多程序員開(kāi)發(fā)出多種版本的“連連看”。這其中,顧芳編寫(xiě)的“阿達(dá)連連看”以其精良的制作廣受好評(píng),這也成為顧方“阿達(dá)系列軟件”的核心產(chǎn)品。并于2004年,取得國(guó)家版權(quán)局的計(jì)算機(jī)軟件登記證書(shū)
    2021-11-11
  • 詳解QT使用QtGui顯示QImage的幾種方法

    詳解QT使用QtGui顯示QImage的幾種方法

    本文主要介紹了QT使用QtGui顯示QImage的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • C++中字符串全排列算法及next_permutation原理詳解

    C++中字符串全排列算法及next_permutation原理詳解

    這篇文章主要為大家詳細(xì)介紹了C++中字符串全排列(遞歸法)和(迭代法)以及next_permutation底層原理,文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-02-02
  • 聊聊C++的mutable和volatile

    聊聊C++的mutable和volatile

    這篇文章主要介紹了C++的mutable和volatile的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)c++,感興趣的朋友可以了解下
    2020-09-09

最新評(píng)論

新干县| 福贡县| 临西县| 双流县| 石城县| 秦皇岛市| 杭锦后旗| 乌兰浩特市| 马尔康县| 白朗县| 宜良县| 绵竹市| 永德县| 许昌市| 海盐县| 赣榆县| 太保市| 永靖县| 江门市| 苍山县| 锦州市| 榆中县| 登封市| 通渭县| 岳池县| 黄山市| 呈贡县| 广宗县| 柘荣县| 丰台区| 兰考县| 锦屏县| 高台县| 洞头县| 新余市| 临清市| 阳东县| 于田县| 金门县| 横峰县| 龙南县|