国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

C++初階之一篇文章教會(huì)你list(模擬實(shí)現(xiàn))

這篇具有很好參考價(jià)值的文章主要介紹了C++初階之一篇文章教會(huì)你list(模擬實(shí)現(xiàn))。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

C++初階之一篇文章教會(huì)你list(模擬實(shí)現(xiàn)),C++初階,c++,list,開發(fā)語(yǔ)言

list模擬實(shí)現(xiàn)

成員類型表
C++初階之一篇文章教會(huì)你list(模擬實(shí)現(xiàn)),C++初階,c++,list,開發(fā)語(yǔ)言

這個(gè)表中列出了C++標(biāo)準(zhǔn)庫(kù)中l(wèi)ist容器的一些成員類型定義。這些類型定義是為了使list能夠與C++標(biāo)準(zhǔn)庫(kù)的其他組件協(xié)同工作,并提供一些通用的標(biāo)準(zhǔn)接口。每個(gè)成員類型的用處:

value_type: 這個(gè)成員類型代表list容器中存儲(chǔ)的數(shù)據(jù)類型,即模板參數(shù)T的類型。

allocator_type: 這個(gè)成員類型代表分配器的類型,用于為容器的內(nèi)存分配和管理。默認(rèn)情況下,使用allocator<value_type>作為分配器。

reference: 這個(gè)成員類型表示對(duì)元素的引用類型。對(duì)于默認(rèn)分配器,它是value_type&,即對(duì)元素的引用。

const_reference: 這個(gè)成員類型表示對(duì)常量元素的引用類型。對(duì)于默認(rèn)分配器,它是const value_type&,即對(duì)常量元素的引用。

pointer: 這個(gè)成員類型表示指向元素的指針類型。對(duì)于默認(rèn)分配器,它是value_type*,即指向元素的指針。

const_pointer: 這個(gè)成員類型表示指向常量元素的指針類型。對(duì)于默認(rèn)分配器,它是const value_type*,即指向常量元素的指針。

iterator: 這個(gè)成員類型是一個(gè)雙向迭代器類型,可以用于遍歷容器的元素。它可以隱式轉(zhuǎn)換為const_iterator,允許在遍歷時(shí)修改元素。

const_iterator: 這個(gè)成員類型也是一個(gè)雙向迭代器類型,用于遍歷常量容器的元素,不允許修改元素。

reverse_iterator: 這個(gè)成員類型是iterator的逆向迭代器,可以從容器尾部向頭部遍歷。

const_reverse_iterator: 這個(gè)成員類型是const_iterator的逆向迭代器,用于從常量容器的尾部向頭部遍歷。

difference_type: 這個(gè)成員類型表示兩個(gè)迭代器之間的距離,通常使用的是ptrdiff_t,與指針的差值類型相同。

size_type: 這個(gè)成員類型表示非負(fù)整數(shù)的類型,通常使用的是size_t,用于表示容器的大小。

這些成員類型的定義使得list容器能夠與其他C++標(biāo)準(zhǔn)庫(kù)的組件以及用戶自定義的代碼進(jìn)行交互,從而實(shí)現(xiàn)更加通用和靈活的功能。

list_node節(jié)點(diǎn)結(jié)構(gòu)定義

定義鏈表的節(jié)點(diǎn)結(jié)構(gòu) list_node,用于存儲(chǔ)鏈表中的每個(gè)元素。讓我們逐一解釋每個(gè)部分的含義。

template<class T>
struct list_node
{
    T _data;            // 存儲(chǔ)節(jié)點(diǎn)的數(shù)據(jù)
    list_node<T>* _next;  // 指向下一個(gè)節(jié)點(diǎn)的指針
    list_node<T>* _prev;  // 指向前一個(gè)節(jié)點(diǎn)的指針

    // 構(gòu)造函數(shù)
    list_node(const T& x = T())
        :_data(x)        // 使用參數(shù) x 初始化 _data
        , _next(nullptr) // 初始化 _next 為 nullptr
        , _prev(nullptr) // 初始化 _prev 為 nullptr
    {}
};

T _data;:存儲(chǔ)節(jié)點(diǎn)中的數(shù)據(jù),類型為模板參數(shù) T,可以是任意數(shù)據(jù)類型。

list_node<T>* _next;:指向下一個(gè)節(jié)點(diǎn)的指針,用于構(gòu)建鏈表結(jié)構(gòu)。初始時(shí)設(shè)為 nullptr,表示當(dāng)前節(jié)點(diǎn)沒有后繼節(jié)點(diǎn)。

list_node<T>* _prev;:指向前一個(gè)節(jié)點(diǎn)的指針,同樣用于構(gòu)建鏈表結(jié)構(gòu)。初始時(shí)設(shè)為 nullptr,表示當(dāng)前節(jié)點(diǎn)沒有前驅(qū)節(jié)點(diǎn)。

構(gòu)造函數(shù) list_node(const T& x = T()):構(gòu)造函數(shù)可以接收一個(gè)參數(shù) x,用于初始化節(jié)點(diǎn)的數(shù)據(jù)。如果沒有傳入?yún)?shù),默認(rèn)構(gòu)造一個(gè)空節(jié)點(diǎn)。

通過(guò)這個(gè)節(jié)點(diǎn)結(jié)構(gòu),你可以創(chuàng)建一個(gè)雙向鏈表list,將不同類型的數(shù)據(jù)存儲(chǔ)在節(jié)點(diǎn)中,并連接節(jié)點(diǎn)以構(gòu)建鏈表的結(jié)構(gòu)。這個(gè)節(jié)點(diǎn)結(jié)構(gòu)為鏈表的實(shí)現(xiàn)提供了基礎(chǔ)。

std::__reverse_iterator逆向迭代器實(shí)現(xiàn)

#pragma once

namespace xzq
{
	// 復(fù)用,迭代器適配器
	template<class Iterator, class Ref, class Ptr>
	struct __reverse_iterator
	{
		Iterator _cur;
		typedef __reverse_iterator<Iterator, Ref, Ptr> RIterator;

		__reverse_iterator(Iterator it)
			:_cur(it)
		{}

		RIterator operator++()
		{
			--_cur;
			return *this;
		}

		RIterator operator--()
		{
			++_cur;
			return *this;
		}

		Ref operator*()
		{
			auto tmp = _cur;
			--tmp;
			return *tmp;
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		bool operator!=(const RIterator& it)
		{
			return _cur != it._cur;
		}
	};
}

說(shuō)明:

__reverse_iterator 類模板定義了一個(gè)逆向迭代器,它有三個(gè)模板參數(shù):Iterator迭代器的類型)、Ref引用類型)和 Ptr指針類型)。
_cur 是一個(gè)私有成員變量,保存當(dāng)前迭代器的位置。
構(gòu)造函數(shù)接受一個(gè)正向迭代器作為參數(shù),并將其存儲(chǔ)在 _cur 成員變量中。
operator++() 重載了遞增操作符,讓迭代器向前移動(dòng)一個(gè)位置。
operator--() 重載了遞減操作符,讓迭代器向后移動(dòng)一個(gè)位置。
operator*() 重載了解引用操作符,返回逆向迭代器指向的元素的引用。
operator->() 重載了成員訪問(wèn)操作符,返回逆向迭代器指向的元素的指針。
operator!=() 重載了不等于操作符,用于判斷兩個(gè)逆向迭代器是否不相等。

這個(gè)逆向迭代器可以用于支持從容器的尾部向頭部的方向進(jìn)行迭代。在 C++ 標(biāo)準(zhǔn)庫(kù)中,std::reverse_iterator 用于實(shí)現(xiàn)類似的功能。

這個(gè)代碼實(shí)現(xiàn)了一個(gè)迭代器適配器。迭代器適配器是一種在現(xiàn)有迭代器基礎(chǔ)上提供不同功能的封裝器,使得原本的迭代器能夠適應(yīng)新的使用場(chǎng)景。

__reverse_iterator 就是一個(gè)逆向迭代器適配器。它封裝了一個(gè)正向迭代器,但通過(guò)重載操作符等方式,使其可以從容器的尾部向頭部進(jìn)行迭代。這樣的適配器能夠讓原本的正向迭代器在逆向遍歷時(shí)更加方便。在下面的list模擬實(shí)現(xiàn)中的反向迭代器函數(shù)需要用到,當(dāng)然它也可以適用于其他容器的模擬實(shí)現(xiàn),因場(chǎng)景而定,并不是所有容器都可以適用。

list迭代器 __list_iterator定義

迭代器 __list_iterator,用于遍歷鏈表中的節(jié)點(diǎn)。讓我們逐一解釋每個(gè)部分的含義。

template<class T, class Ref, class Ptr>
struct __list_iterator
{
    
	typedef list_node<T> Node;  // 定義一個(gè)類型別名 Node,用于表示 list 節(jié)點(diǎn)的類型

	typedef __list_iterator<T, Ref, Ptr> iterator;  // 定義一個(gè)類型別名 iterator,用于表示 list 迭代器的類型

	typedef bidirectional_iterator_tag iterator_category;  // 定義迭代器的分類,這里是雙向迭代器
	
	typedef T value_type;  // 定義元素的類型,即模板參數(shù) T

	typedef Ptr pointer;  // 定義指向元素的指針類型,用于迭代器

	typedef Ref reference;  // 定義對(duì)元素的引用類型,用于迭代器

	typedef ptrdiff_t difference_type;  // 定義表示迭代器之間距離的類型

    Node* _node;  // 指向鏈表中的節(jié)點(diǎn)

    __list_iterator(Node* node)
        :_node(node)  // 初始化迭代器,指向給定的節(jié)點(diǎn)
    {}

    bool operator!=(const iterator& it) const
    {
        return _node != it._node;  // 比較兩個(gè)迭代器是否不相等
    }

    bool operator==(const iterator& it) const
    {
        return _node == it._node;  // 比較兩個(gè)迭代器是否相等
    }

    Ref operator*()
    {
        return _node->_data;  // 返回當(dāng)前節(jié)點(diǎn)的數(shù)據(jù)
    }

    Ptr operator->()
    { 
        return &(operator*());  // 返回當(dāng)前節(jié)點(diǎn)數(shù)據(jù)的地址
    }

    // ++it
    iterator& operator++()
    {
        _node = _node->_next;  // 迭代器自增,指向下一個(gè)節(jié)點(diǎn)
        return *this;
    }
    
    // it++
    iterator operator++(int)
    {
        iterator tmp(*this);  // 創(chuàng)建一個(gè)臨時(shí)迭代器保存當(dāng)前迭代器
        _node = _node->_next;  // 迭代器自增,指向下一個(gè)節(jié)點(diǎn)
        return tmp;  // 返回保存的臨時(shí)迭代器
    }

    // --it
    iterator& operator--()
    {
        _node = _node->_prev;  // 迭代器自減,指向前一個(gè)節(jié)點(diǎn)
        return *this;
    }

    // it--
    iterator operator--(int)
    {
        iterator tmp(*this);  // 創(chuàng)建一個(gè)臨時(shí)迭代器保存當(dāng)前迭代器
        _node = _node->_prev;  // 迭代器自減,指向前一個(gè)節(jié)點(diǎn)
        return tmp;  // 返回保存的臨時(shí)迭代器
    }
};

這個(gè)迭代器結(jié)構(gòu)為鏈表提供了遍歷節(jié)點(diǎn)的能力。它可以用于循環(huán)遍歷鏈表的每個(gè)元素,提供了類似于指針的行為,使得遍歷鏈表變得更加方便。

這里提一下迭代器類型的分類:

C++ 標(biāo)準(zhǔn)庫(kù)中的迭代器分為五種主要類型,每種類型提供了不同的功能和支持的操作。這些類型分別是:

輸入迭代器(Input Iterator):只允許從容器中讀取元素,但不能修改容器內(nèi)的元素。只支持逐個(gè)移動(dòng)、解引用、比較以及比較是否相等等操作。輸入迭代器通常用于算法中,如 std::find()。

輸出迭代器(Output Iterator):只允許向容器寫入元素,但不能讀取容器內(nèi)的元素。支持逐個(gè)移動(dòng)和逐個(gè)寫入元素等操作。

前向迭代器(Forward Iterator):類似于輸入迭代器,但支持多次解引用。前向迭代器可以用于一些需要多次迭代的操作,如遍歷一個(gè)單鏈表。

雙向迭代器(Bidirectional Iterator):在前向迭代器的基礎(chǔ)上,增加了向前遍歷的能力。除了支持輸入迭代器的操作外,還支持向前移動(dòng)和逐個(gè)向前移動(dòng)元素等操作。

隨機(jī)訪問(wèn)迭代器(Random Access Iterator):是最強(qiáng)大的迭代器類型。除了支持前向迭代器和雙向迭代器的所有操作外,還支持類似指針的算術(shù)操作,如加法、減法,以及隨機(jī)訪問(wèn)容器中的元素。隨機(jī)訪問(wèn)迭代器通常用于數(shù)組等支持隨機(jī)訪問(wèn)的數(shù)據(jù)結(jié)構(gòu)中。

在上面的代碼中,typedef bidirectional_iterator_tag iterator_category; 表示這個(gè)迭代器是雙向迭代器類型,因此它應(yīng)該支持前向和雙向迭代器的所有操作,包括移動(dòng)、解引用、比較等。這是為了確保這個(gè)迭代器在遍歷 list 類的容器元素時(shí)能夠正常工作。

list類成員定義

下面的代碼是C++ 中雙向鏈表模板類 list 的類定義部分。這個(gè)類定義了一些公共的成員類型和私有成員變量來(lái)支持鏈表的操作。讓我們逐一解釋每個(gè)部分的含義。

template<class T>
class list
{
    typedef list_node<T> Node;
public:
    // 定義迭代器類型
    typedef __list_iterator<T, T&, T*> iterator;
    typedef __list_iterator<T, const T&, const T*> const_iterator;

    typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;
    typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;

private:
    Node* _head;
};

typedef list_node<T> Node;:定義一個(gè)別名 Node,代表鏈表節(jié)點(diǎn)類型 list_node<T>

typedef __list_iterator<T, T&, T*> iterator;:定義了鏈表的正向迭代器類型 iterator,它使用 __list_iterator 結(jié)構(gòu)模板,并指定了相應(yīng)的參數(shù)類型。

typedef __list_iterator<T, const T&, const T*> const_iterator;:定義了鏈表的常量正向迭代器類型 const_iterator,用于在不修改鏈表元素的情況下遍歷鏈表。

typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;:定義了鏈表的反向迭代器類型 reverse_iterator,這個(gè)迭代器從鏈表末尾向鏈表開頭遍歷。

typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;:定義了鏈表的常量反向迭代器類型 const_reverse_iterator。

Node* _head;:鏈表的私有成員變量,指向鏈表的頭節(jié)點(diǎn)。

這個(gè)部分的代碼定義了 list 類的公共成員類型和私有成員變量,為實(shí)現(xiàn)鏈表的操作和管理提供了基礎(chǔ)。

list成員函數(shù)定義

1.begin()、end()、rbegin()和rend()

const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

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

		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

這部分代碼是關(guān)于 list 類的迭代器成員函數(shù)的定義。它們用于返回不同類型的迭代器,使得用戶可以遍歷 list 容器的元素。

const_iterator begin() const: 這是一個(gè)常量成員函數(shù),返回一個(gè)常量迭代器,它指向容器中的第一個(gè)元素(節(jié)點(diǎn))。由于是常量迭代器,所以不允許通過(guò)它修改容器內(nèi)的元素。

const_iterator end() const: 這也是一個(gè)常量成員函數(shù),返回一個(gè)常量迭代器,它指向容器末尾的“尾后”位置,即不存在的元素位置。常量迭代器不能用于修改元素。

iterator begin(): 這是一個(gè)非常量成員函數(shù),返回一個(gè)非常量迭代器,它指向容器中的第一個(gè)元素(節(jié)點(diǎn))。允許通過(guò)這個(gè)迭代器修改容器內(nèi)的元素。

iterator end(): 這也是一個(gè)非常量成員函數(shù),返回一個(gè)非常量迭代器,它指向容器末尾的“尾后”位置,即不存在的元素位置。非常量迭代器可以用于修改元素。

reverse_iterator rbegin(): 這是一個(gè)返回反向迭代器的函數(shù),它將 end() 的迭代器作為參數(shù)傳遞給 reverse_iterator 構(gòu)造函數(shù),從而返回一個(gè)指向容器末尾的反向迭代器。

reverse_iterator rend(): 這是一個(gè)返回反向迭代器的函數(shù),它將 begin() 的迭代器作為參數(shù)傳遞給 reverse_iterator 構(gòu)造函數(shù),從而返回一個(gè)指向容器開始的反向迭代器。

這些函數(shù)的目的是為了方便用戶在不同情況下遍歷容器元素,包括正向遍歷和反向遍歷,以及使用常量或非常量迭代器。通過(guò)這些迭代器,用戶可以在 list 容器中輕松訪問(wèn)和操作元素。

2.empty_init()

void empty_init()
{
    _head = new Node; // 創(chuàng)建一個(gè)新的節(jié)點(diǎn)作為鏈表頭部
    _head->_next = _head; // 將頭部節(jié)點(diǎn)的下一個(gè)指針指向自身,表示鏈表為空
    _head->_prev = _head; // 將頭部節(jié)點(diǎn)的前一個(gè)指針也指向自身,表示鏈表為空
}

這是 list 類中的一個(gè)私有成員函數(shù) empty_init(),它用于初始化一個(gè)空的鏈表。

該函數(shù)的目的是在創(chuàng)建一個(gè)新的空鏈表時(shí),為頭部節(jié)點(diǎn) _head 初始化正確的指針,使得鏈表為空。鏈表的頭部節(jié)點(diǎn) _head 用來(lái)標(biāo)識(shí)鏈表的起始位置和結(jié)束位置。

在這個(gè)函數(shù)中,首先通過(guò) new 運(yùn)算符創(chuàng)建一個(gè)新的節(jié)點(diǎn)作為鏈表的頭部。然后,將頭部節(jié)點(diǎn)的 _next 指針和 _prev 指針都指向自身,表示鏈表為空。這種情況下,鏈表的頭部節(jié)點(diǎn)既是首節(jié)點(diǎn)也是尾節(jié)點(diǎn),形成一個(gè)環(huán)狀的鏈表結(jié)構(gòu)。

list 類的構(gòu)造函數(shù)中,通過(guò)調(diào)用 empty_init() 來(lái)創(chuàng)建一個(gè)空鏈表。這在后續(xù)的操作中為鏈表的插入、刪除等操作提供了正確的基礎(chǔ)。

3.構(gòu)造函數(shù)定義

template <class InputIterator>  
list(InputIterator first, InputIterator last)
{
    empty_init(); // 初始化一個(gè)空鏈表

    while (first != last)
    {
        push_back(*first); // 將當(dāng)前迭代器指向的元素添加到鏈表尾部
        ++first; // 移動(dòng)迭代器到下一個(gè)元素
    }
}

list 類的構(gòu)造函數(shù)模板,它接受一個(gè)范圍內(nèi)的元素,并將這些元素添加到鏈表中。
這個(gè)構(gòu)造函數(shù)使用了一個(gè)模板參數(shù) InputIterator,它表示輸入迭代器的類型。這樣,構(gòu)造函數(shù)可以接受不同類型的迭代器,例如普通指針、list 的迭代器等。

在構(gòu)造函數(shù)中,首先調(diào)用 empty_init() 函數(shù)來(lái)初始化一個(gè)空鏈表,確保鏈表頭部的 _head 節(jié)點(diǎn)正確初始化。

然后,使用一個(gè)循環(huán)遍歷輸入迭代器范圍內(nèi)的元素。在每次循環(huán)中,通過(guò) push_back() 函數(shù)將當(dāng)前迭代器指向的元素添加到鏈表的尾部。之后,將迭代器向前移動(dòng)一個(gè)位置,以便處理下一個(gè)元素。

list()
{
    empty_init(); // 初始化一個(gè)空鏈表
}

這是 list 類的無(wú)參構(gòu)造函數(shù),它用于創(chuàng)建一個(gè)空的鏈表。

這個(gè)構(gòu)造函數(shù)不接受任何參數(shù),它只是在對(duì)象創(chuàng)建時(shí)將 _head 節(jié)點(diǎn)初始化為一個(gè)空鏈表。調(diào)用 empty_init() 函數(shù)會(huì)創(chuàng)建一個(gè)只包含 _head 節(jié)點(diǎn)的鏈表,該節(jié)點(diǎn)的 _next_prev 都指向自身,表示鏈表為空。

list(const list<T>& lt)
{
    empty_init(); // 初始化一個(gè)空鏈表

    list<T> tmp(lt.begin(), lt.end()); // 使用迭代器從 lt 創(chuàng)建一個(gè)臨時(shí)鏈表
    swap(tmp); // 交換臨時(shí)鏈表和當(dāng)前鏈表,完成拷貝操作
}

這是 list 類的拷貝構(gòu)造函數(shù),它用于創(chuàng)建一個(gè)新鏈表,該鏈表與另一個(gè)已存在的鏈表 lt 相同

在這個(gè)構(gòu)造函數(shù)中,首先通過(guò)調(diào)用 empty_init() 函數(shù)初始化了一個(gè)空鏈表,然后創(chuàng)建了一個(gè)臨時(shí)鏈表 tmp,這個(gè)臨時(shí)鏈表的元素和鏈表 lt 中的元素相同,通過(guò)迭代器從 lt 范圍內(nèi)創(chuàng)建。接著,通過(guò)調(diào)用 swap() 函數(shù)將當(dāng)前鏈表與臨時(shí)鏈表 tmp 交換,從而實(shí)現(xiàn)了鏈表的拷貝。

這種方式能夠?qū)崿F(xiàn)拷貝構(gòu)造的效果,因?yàn)樵?swap() 函數(shù)中,臨時(shí)鏈表 tmp 的資源會(huì)交給當(dāng)前鏈表,而臨時(shí)鏈表 tmp 會(huì)被銷毀,從而實(shí)現(xiàn)了鏈表內(nèi)容的拷貝。

4.swap

void swap(list<T>& x)
{
    std::swap(_head, x._head); // 交換兩個(gè)鏈表的頭結(jié)點(diǎn)指針
}

這是 list 類的成員函數(shù) swap,它用于交換兩個(gè)鏈表的內(nèi)容。

在這個(gè)函數(shù)中,通過(guò)調(diào)用標(biāo)準(zhǔn)庫(kù)函數(shù) std::swap,將當(dāng)前鏈表的頭結(jié)點(diǎn)指針 _head 與另一個(gè)鏈表 x 的頭結(jié)點(diǎn)指針 _head 進(jìn)行交換。這個(gè)操作會(huì)導(dǎo)致兩個(gè)鏈表的內(nèi)容被互相交換,但是實(shí)際上并沒有復(fù)制鏈表中的元素,只是交換了鏈表的結(jié)構(gòu)。

這種交換操作通常在需要交換兩個(gè)對(duì)象的內(nèi)容時(shí)使用,它可以在不復(fù)制數(shù)據(jù)的情況下實(shí)現(xiàn)兩個(gè)對(duì)象之間的內(nèi)容互換,從而提高了效率。

需要注意的是,這個(gè)函數(shù)只是交換了鏈表的頭結(jié)點(diǎn)指針,而鏈表中的元素順序沒有改變。

5.析構(gòu)函數(shù)定義

~list()
{
    clear();         // 清空鏈表中的所有元素
    delete _head;    // 刪除頭結(jié)點(diǎn)
    _head = nullptr; // 將頭結(jié)點(diǎn)指針置為空指針
}

這是 list 類的析構(gòu)函數(shù),用于銷毀鏈表對(duì)象。

在這個(gè)析構(gòu)函數(shù)中,首先調(diào)用了成員函數(shù) clear() 來(lái)清空鏈表中的所有元素,確保在刪除鏈表之前釋放所有資源。然后,使用 delete 關(guān)鍵字釋放頭結(jié)點(diǎn)的內(nèi)存。最后,將頭結(jié)點(diǎn)指針 _head 置為空指針,以避免出現(xiàn)野指針。

這樣,在鏈表對(duì)象被銷毀時(shí),它所占用的內(nèi)存將會(huì)被正確地釋放,從而防止內(nèi)存泄漏。

6.clear()

void clear()
{
    iterator it = begin(); // 獲取鏈表的起始迭代器
    while (it != end())    // 遍歷鏈表
    {
        it = erase(it);    // 使用 erase() 函數(shù)刪除當(dāng)前元素,并將迭代器指向下一個(gè)元素
    }
}

這是 list 類的 clear() 成員函數(shù),用于清空鏈表中的所有元素。

在這個(gè)函數(shù)中,首先獲取鏈表的起始迭代器 begin(),然后通過(guò)一個(gè)循環(huán)遍歷鏈表中的所有元素。在循環(huán)內(nèi)部,調(diào)用了 erase() 函數(shù)來(lái)刪除當(dāng)前迭代器指向的元素,并將迭代器更新為指向被刪除元素的下一個(gè)元素。這樣可以確保鏈表中的所有元素都被逐個(gè)刪除。

需要注意的是,erase() 函數(shù)在刪除元素后會(huì)返回指向下一個(gè)元素的迭代器,因此在每次循環(huán)迭代時(shí)更新迭代器是必要的,以便繼續(xù)正確地遍歷鏈表。

總之,這個(gè) clear() 函數(shù)用于釋放鏈表中的所有元素,并確保鏈表變?yōu)榭真湵怼?/p>

7.push_back

void push_back(const T& x)
{
    Node* tail = _head->_prev; // 獲取當(dāng)前鏈表的末尾節(jié)點(diǎn)
    Node* newnode = new Node(x); // 創(chuàng)建一個(gè)新節(jié)點(diǎn),保存新元素 x

    tail->_next = newnode; // 更新末尾節(jié)點(diǎn)的下一個(gè)指針,指向新節(jié)點(diǎn)
    newnode->_prev = tail; // 新節(jié)點(diǎn)的前一個(gè)指針指向原末尾節(jié)點(diǎn)
    newnode->_next = _head; // 新節(jié)點(diǎn)的下一個(gè)指針指向頭節(jié)點(diǎn)
    _head->_prev = newnode; // 頭節(jié)點(diǎn)的前一個(gè)指針指向新節(jié)點(diǎn),完成插入操作
}

這是 list 類的 push_back() 成員函數(shù),用于在鏈表的末尾添加一個(gè)新元素。

在這個(gè)函數(shù)中,首先獲取當(dāng)前鏈表的末尾節(jié)點(diǎn)(尾節(jié)點(diǎn)的 _prev 指向鏈表的最后一個(gè)元素),然后創(chuàng)建一個(gè)新的節(jié)點(diǎn) newnode,并將新元素 x 存儲(chǔ)在新節(jié)點(diǎn)中。接著,更新末尾節(jié)點(diǎn)的 _next 指針,使其指向新節(jié)點(diǎn),然后更新新節(jié)點(diǎn)的 _prev 指針,使其指向原末尾節(jié)點(diǎn)。同時(shí),將新節(jié)點(diǎn)的 _next 指針指向頭節(jié)點(diǎn),完成循環(huán)鏈表的連接。最后,更新頭節(jié)點(diǎn)的 _prev 指針,使其指向新節(jié)點(diǎn),確保鏈表的連接是完整的。

需要注意的是,這個(gè)函數(shù)在鏈表末尾添加了一個(gè)新元素,不影響其他元素的相對(duì)位置。

8.push_front

void push_front(const T& x)
{
    insert(begin(), x); // 調(diào)用 insert 函數(shù),在頭部插入新元素 x
}

這個(gè)函數(shù)簡(jiǎn)單地調(diào)用了 insert 函數(shù),將新元素 x 插入到鏈表的頭部。

9.insert

iterator insert(iterator pos, const T& x)
{
    Node* cur = pos._node; // 獲取當(dāng)前位置的節(jié)點(diǎn)
    Node* prev = cur->_prev; // 獲取當(dāng)前位置節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)

    Node* newnode = new Node(x); // 創(chuàng)建一個(gè)新節(jié)點(diǎn),保存新元素 x

    prev->_next = newnode; // 更新前一個(gè)節(jié)點(diǎn)的下一個(gè)指針,指向新節(jié)點(diǎn)
    newnode->_prev = prev; // 新節(jié)點(diǎn)的前一個(gè)指針指向前一個(gè)節(jié)點(diǎn)
    newnode->_next = cur; // 新節(jié)點(diǎn)的下一個(gè)指針指向當(dāng)前位置節(jié)點(diǎn)
    cur->_prev = newnode; // 當(dāng)前位置節(jié)點(diǎn)的前一個(gè)指針指向新節(jié)點(diǎn),完成插入操作

    return iterator(newnode); // 返回指向新節(jié)點(diǎn)的迭代器
}

insert 函數(shù)中,首先獲取當(dāng)前位置節(jié)點(diǎn) pos 和其前一個(gè)節(jié)點(diǎn) prev,然后創(chuàng)建一個(gè)新節(jié)點(diǎn) newnode 并將新元素 x 存儲(chǔ)在新節(jié)點(diǎn)中。接著,更新前一個(gè)節(jié)點(diǎn)的 _next 指針,使其指向新節(jié)點(diǎn),然后更新新節(jié)點(diǎn)的 _prev 指針,使其指向前一個(gè)節(jié)點(diǎn)。同時(shí),將新節(jié)點(diǎn)的 _next 指針指向當(dāng)前位置節(jié)點(diǎn) cur,完成插入操作。最后,更新當(dāng)前位置節(jié)點(diǎn)的 _prev 指針,使其指向新節(jié)點(diǎn),確保鏈表的連接是完整的。最后,函數(shù)返回一個(gè)指向新節(jié)點(diǎn)的迭代器,表示插入操作完成后的位置。

10.erase

iterator erase(iterator pos)
{
    assert(pos != end()); // 斷言:確保 pos 不等于鏈表的結(jié)束迭代器

    Node* cur = pos._node; // 獲取當(dāng)前位置的節(jié)點(diǎn)
    Node* prev = cur->_prev; // 獲取當(dāng)前位置節(jié)點(diǎn)的前一個(gè)節(jié)點(diǎn)
    Node* next = cur->_next; // 獲取當(dāng)前位置節(jié)點(diǎn)的后一個(gè)節(jié)點(diǎn)

    prev->_next = next; // 更新前一個(gè)節(jié)點(diǎn)的下一個(gè)指針,指向后一個(gè)節(jié)點(diǎn)
    next->_prev = prev; // 更新后一個(gè)節(jié)點(diǎn)的前一個(gè)指針,指向前一個(gè)節(jié)點(diǎn)
    delete cur; // 刪除當(dāng)前位置的節(jié)點(diǎn)

    return iterator(next); // 返回指向后一個(gè)節(jié)點(diǎn)的迭代器,表示刪除操作完成后的位置
}

這部分代碼實(shí)現(xiàn)了從鏈表中刪除指定位置元素的功能。

erase 函數(shù)中,首先使用斷言來(lái)確保刪除位置 pos 不是鏈表的結(jié)束迭代器。然后,獲取當(dāng)前位置節(jié)點(diǎn) pos、其前一個(gè)節(jié)點(diǎn) prev 和后一個(gè)節(jié)點(diǎn) next。接著,更新前一個(gè)節(jié)點(diǎn)的 _next 指針,使其指向后一個(gè)節(jié)點(diǎn),同時(shí)更新后一個(gè)節(jié)點(diǎn)的 _prev 指針,使其指向前一個(gè)節(jié)點(diǎn)。這樣,當(dāng)前位置節(jié)點(diǎn)就從鏈表中斷開了。最后,釋放當(dāng)前位置節(jié)點(diǎn)的內(nèi)存空間,并返回一個(gè)指向后一個(gè)節(jié)點(diǎn)的迭代器,表示刪除操作完成后的位置。

11.pop_back()和pop_front()

void pop_back()
{
    erase(--end()); // 通過(guò) erase 函數(shù)刪除鏈表末尾的元素
}

pop_back 函數(shù)通過(guò)將鏈表的結(jié)束迭代器向前移動(dòng)一個(gè)位置,然后調(diào)用 erase 函數(shù)來(lái)刪除該位置的元素,實(shí)現(xiàn)了從鏈表末尾刪除一個(gè)元素的操作。

void pop_front()
{
    erase(begin()); // 通過(guò) erase 函數(shù)刪除鏈表頭部的元素
}

pop_front 函數(shù)直接調(diào)用 erase 函數(shù),刪除鏈表頭部的元素,實(shí)現(xiàn)了從鏈表頭部刪除一個(gè)元素的操作。

這兩個(gè)函數(shù)分別對(duì)應(yīng)于從鏈表的末尾和頭部刪除元素的操作,通過(guò)調(diào)用 erase 函數(shù)來(lái)完成刪除操作,從而保持了鏈表的連接性。

12.empty()、size()、front()和back()

bool list<T>::empty() const
{
    return begin() == end(); // 判斷 begin() 是否等于 end() 來(lái)確定是否為空
}

typename list<T>::size_t list<T>::size() const
{
    size_t count = 0;
    for (const_iterator it = begin(); it != end(); ++it)
    {
        ++count;
    }
    return count; // 遍歷鏈表來(lái)計(jì)算元素個(gè)數(shù)
}

typename list<T>::reference list<T>::front()
{
    assert(!empty()); // 如果鏈表為空,則拋出斷言
    return *begin(); // 返回鏈表的第一個(gè)元素
}

typename list<T>::const_reference list<T>::front() const
{
    assert(!empty()); // 如果鏈表為空,則拋出斷言
    return *begin(); // 返回鏈表的第一個(gè)元素
}

typename list<T>::reference list<T>::back()
{
    assert(!empty()); // 如果鏈表為空,則拋出斷言
    return *(--end()); // 返回鏈表的最后一個(gè)元素
}

typename list<T>::const_reference list<T>::back() const
{
    assert(!empty()); // 如果鏈表為空,則拋出斷言
    return *(--end()); // 返回鏈表的最后一個(gè)元素
}

上述代碼實(shí)現(xiàn)了 empty() 函數(shù)用于判斷鏈表是否為空,size() 函數(shù)用于獲取鏈表元素個(gè)數(shù),front() 函數(shù)用于獲取鏈表第一個(gè)元素,以及 back() 函數(shù)用于獲取鏈表最后一個(gè)元素。注意函數(shù)中的斷言用于確保在鏈表為空時(shí)不執(zhí)行非法操作。

13.resize

template<class T>
void list<T>::resize(size_t n, const T& val)
{
    if (n < size()) {
        iterator it = begin();
        std::advance(it, n); // 定位到新的尾部位置
        while (it != end()) {
            it = erase(it); // 從尾部截?cái)?,刪除多余的元素
        }
    }
    else if (n > size()) {
        insert(end(), n - size(), val); // 插入足夠數(shù)量的默認(rèn)值元素
    }
}

如果 n 小于當(dāng)前鏈表的大小size(),意味著你想要縮小鏈表的大小。在這種情況下,函數(shù)會(huì)迭代遍歷鏈表,從尾部開始刪除多余的元素,直到鏈表的大小等于 n。

首先,函數(shù)會(huì)使用 begin() 獲取鏈表的起始迭代器,然后使用 std::advance 函數(shù)將迭代器向前移動(dòng) n 個(gè)位置,使其指向新的尾部位置。

接下來(lái),函數(shù)使用 erase 函數(shù)將從新尾部位置到鏈表末尾的所有元素刪除,從而使鏈表的大小減小到 n。

如果 n 大于當(dāng)前鏈表的大小,表示你想要增大鏈表的大小。在這種情況下,函數(shù)會(huì)插入足夠數(shù)量的值為 val 的元素到鏈表的末尾,直到鏈表的大小等于 n。

函數(shù)會(huì)使用 insert 函數(shù)在鏈表的末尾插入 n - size() 個(gè)值為 val 的元素,從而使鏈表的大小增大到 n

14.賦值運(yùn)算符重載

list<T>& operator=(list<T> lt)
{
    swap(lt); // 交換當(dāng)前對(duì)象和傳入對(duì)象的內(nèi)容
    return *this; // 返回當(dāng)前對(duì)象的引用
}

這是一個(gè)賦值運(yùn)算符重載函數(shù),它采用了拷貝并交換(Copy and Swap)的技巧來(lái)實(shí)現(xiàn)賦值操作。

這是一個(gè)成員函數(shù),用于將一個(gè) list<T> 類型的對(duì)象賦值給當(dāng)前的對(duì)象。
參數(shù) lt 是通過(guò)值傳遞的,所以會(huì)調(diào)用 list<T> 的拷貝構(gòu)造函數(shù)創(chuàng)建一個(gè)臨時(shí)副本。
然后,通過(guò) swap(lt) 調(diào)用 swap 函數(shù)來(lái)交換當(dāng)前對(duì)象和臨時(shí)副本的內(nèi)容。在交換后,臨時(shí)副本的數(shù)據(jù)會(huì)被賦值給當(dāng)前對(duì)象,而臨時(shí)副本會(huì)被銷毀。由于交換是高效的操作,可以避免大量的數(shù)據(jù)復(fù)制。
最后,函數(shù)返回當(dāng)前對(duì)象的引用,以支持連續(xù)賦值操作。
這種方式不僅避免了手動(dòng)管理內(nèi)存的麻煩,還確保了異常安全,因?yàn)榕R時(shí)副本在函數(shù)結(jié)束時(shí)會(huì)被正確銷毀。

list模擬實(shí)現(xiàn)全部代碼

#pragma once

#include <assert.h>
#include <iostream>

namespace xzq
{
	template<class T>
	struct list_node
	{
		T _data;
		list_node<T>* _next;
		list_node<T>* _prev;

		list_node(const T& x = T())
			:_data(x)
			, _next(nullptr)
			, _prev(nullptr)
		{}
	};

	template<class T, class Ref, class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef __list_iterator<T, Ref, Ptr> iterator;

		typedef bidirectional_iterator_tag iterator_category;
		typedef T value_type;
		typedef Ptr pointer;
		typedef Ref reference;
		typedef ptrdiff_t difference_type;


		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		bool operator!=(const iterator& it) const
		{
			return _node != it._node;
		}

		bool operator==(const iterator& it) const
		{
			return _node == it._node;
		}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{ 
			return &(operator*());
		}

		// ++it
		iterator& operator++()
		{
			_node = _node->_next;
			return *this;
		}
		
		// it++
		iterator operator++(int)
		{
			iterator tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		// --it
		iterator& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		// it--
		iterator operator--(int)
		{
			iterator tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node;
	public:
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;

		typedef __reverse_iterator<iterator, T&, T*> reverse_iterator;
		typedef __reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;


		const_iterator begin() const
		{
			return const_iterator(_head->_next);
		}

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

		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}

		reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}

		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}

		void empty_init()
		{
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
		}

		template <class InputIterator>  
		list(InputIterator first, InputIterator last)
		{
			empty_init();

			while (first != last)
			{
				push_back(*first);
				++first;
			}
		}

		list()
		{
			empty_init();
		}

		void swap(list<T>& x)
		{
			std::swap(_head, x._head);
		}
		list(const list<T>& lt)
		{
			empty_init();
			list<T> tmp(lt.begin(), lt.end());
			swap(tmp);
		}

		list<T>& operator=(list<T> lt)
		{
			swap(lt);
			return *this;
		}

		~list()
		{
			clear();
			delete _head;
			_head = nullptr;
		}

		void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);
			}
		}

		void push_back(const T& x)
		{
			Node* tail = _head->_prev;
			Node* newnode = new Node(x);

			tail->_next = newnode;
			newnode->_prev = tail;
			newnode->_next = _head;
			_head->_prev = newnode;

			//insert(end(), x);
		}

		void push_front(const T& x)
		{
			insert(begin(), x);
		}

		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;

			Node* newnode = new Node(x);

			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);
		}

		void pop_back()
		{
			erase(--end());
		}

		void pop_front()
		{
			erase(begin());
		}

		iterator erase(iterator pos)
		{
			assert(pos != end());

			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			prev->_next = next;
			next->_prev = prev;
			delete cur;

			return iterator(next);
		}

		bool list<T>::empty() const
		{
			return begin() == end(); // 判斷 begin() 是否等于 end() 來(lái)確定是否為空
		}

		typename list<T>::size_t list<T>::size() const
		{
			size_t count = 0;
			for (const_iterator it = begin(); it != end(); ++it)
			{
				++count;
			}
			return count; // 遍歷鏈表來(lái)計(jì)算元素個(gè)數(shù)
		}

		typename list<T>::reference list<T>::front()
		{
			assert(!empty()); // 如果鏈表為空,則拋出斷言
			return *begin(); // 返回鏈表的第一個(gè)元素
		}

		typename list<T>::const_reference list<T>::front() const
		{
			assert(!empty()); // 如果鏈表為空,則拋出斷言
			return *begin(); // 返回鏈表的第一個(gè)元素
		}

		typename list<T>::reference list<T>::back()
		{
			assert(!empty()); // 如果鏈表為空,則拋出斷言
			return *(--end()); // 返回鏈表的最后一個(gè)元素
		}

		typename list<T>::const_reference list<T>::back() const
		{
			assert(!empty()); // 如果鏈表為空,則拋出斷言
			return *(--end()); // 返回鏈表的最后一個(gè)元素
		}
		void resize(size_t n, const T& val = T())
		{
			if (n < size()) {
				iterator it = begin();
				std::advance(it, n);
				while (it != end()) {
					it = erase(it); // 從尾部截?cái)?,刪除多余的元素
				}
			}
			else if (n > size()) {
				insert(end(), n - size(), val); // 插入足夠數(shù)量的默認(rèn)值元素
			}
		}
	private:
		Node* _head;
	};
}

list 和 vector的區(qū)別

通過(guò)模擬實(shí)現(xiàn) listvector,你可以更好地理解它們之間的區(qū)別和特點(diǎn)。這兩者是 C++ 標(biāo)準(zhǔn)庫(kù)中的序列式容器,但它們?cè)趦?nèi)部實(shí)現(xiàn)和使用場(chǎng)景上有很大的區(qū)別。

底層實(shí)現(xiàn):

list 通常是一個(gè)雙向鏈表,每個(gè)節(jié)點(diǎn)都包含了數(shù)據(jù)和指向前一個(gè)和后一個(gè)節(jié)點(diǎn)的指針。這使得在任何位置進(jìn)行插入和刪除操作都是高效的,但隨機(jī)訪問(wèn)和內(nèi)存占用可能相對(duì)較差。
vector 是一個(gè)動(dòng)態(tài)數(shù)組,元素在內(nèi)存中是連續(xù)存儲(chǔ)的。這使得隨機(jī)訪問(wèn)非常高效,但插入和刪除操作可能需要移動(dòng)大量的元素,效率較低。

插入和刪除操作:

list 中,插入和刪除操作是高效的,無(wú)論是在容器的任何位置還是在開頭和結(jié)尾。這使得 list 在需要頻繁插入和刪除操作時(shí)非常適用。
vector 中,插入和刪除操作可能需要移動(dòng)元素,特別是在容器的中間或開頭。因此,當(dāng)涉及大量插入和刪除操作時(shí),vector 可能不如 list 效率高。

隨機(jī)訪問(wèn):

list 不支持隨機(jī)訪問(wèn),即不能通過(guò)索引直接訪問(wèn)元素,必須通過(guò)迭代器逐個(gè)遍歷。
vector 支持隨機(jī)訪問(wèn),可以通過(guò)索引快速訪問(wèn)元素,具有良好的隨機(jī)訪問(wèn)性能。

內(nèi)存占用:

由于 list 使用鏈表存儲(chǔ)元素,每個(gè)節(jié)點(diǎn)都需要額外的指針來(lái)指向前后節(jié)點(diǎn),可能會(huì)導(dǎo)致更多的內(nèi)存占用。
vector 在內(nèi)存中是連續(xù)存儲(chǔ)的,通常占用的內(nèi)存較少。

迭代器失效:

list 中,插入和刪除操作不會(huì)導(dǎo)致迭代器失效,因?yàn)楣?jié)點(diǎn)之間的關(guān)系不會(huì)改變。
vector 中,插入和刪除操作可能導(dǎo)致內(nèi)存重新分配,從而使原來(lái)的迭代器失效。

綜上所述,如果你需要頻繁進(jìn)行插入和刪除操作,而對(duì)于隨機(jī)訪問(wèn)性能沒有特別高的要求,那么使用 list 是一個(gè)不錯(cuò)的選擇。而如果你更注重隨機(jī)訪問(wèn)性能,可以選擇使用 vector。當(dāng)然,在實(shí)際開發(fā)中,還需要根據(jù)具體情況權(quán)衡使用哪種容器。

結(jié)語(yǔ)

有興趣的小伙伴可以關(guān)注作者,如果覺得內(nèi)容不錯(cuò),請(qǐng)給個(gè)一鍵三連吧,蟹蟹你喲?。?!
制作不易,如有不正之處敬請(qǐng)指出
感謝大家的來(lái)訪,UU們的觀看是我堅(jiān)持下去的動(dòng)力
在時(shí)間的催化劑下,讓我們彼此都成為更優(yōu)秀的人吧?。?!
(創(chuàng)作128天紀(jì)念日,暫時(shí)還沒有想好怎么分享,下次再寫嘍)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-652119.html

到了這里,關(guān)于C++初階之一篇文章教會(huì)你list(模擬實(shí)現(xiàn))的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • C++初階之一篇文章讓你掌握string類(了解和使用)

    C++初階之一篇文章讓你掌握string類(了解和使用)

    學(xué)習(xí) string 類是在 C++ 中非常重要的一步,string 類是 C++ 標(biāo)準(zhǔn)庫(kù)提供的用于處理字符串的類,它相比 C 語(yǔ)言中的字符串處理函數(shù)更為高級(jí)、靈活和安全。以下是學(xué)習(xí) string 類的一些重要理由: 功能強(qiáng)大 :string 類提供了豐富的成員函數(shù)和操作符,用于處理字符串的拼接、查找、

    2024年02月15日
    瀏覽(34)
  • 【C++】一篇文章帶你深入了解list

    【C++】一篇文章帶你深入了解list

    list是可以在常數(shù)范圍內(nèi)在任意位置進(jìn)行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。 list的底層是雙向鏈表結(jié)構(gòu),雙向鏈表中每個(gè)元素存儲(chǔ)在互不相關(guān)的獨(dú)立節(jié)點(diǎn)中,在節(jié)點(diǎn)中通過(guò)指針指向其前一個(gè)元素和后一個(gè)元素。 list與forward_list非常相似:最主要的不同在

    2024年04月23日
    瀏覽(30)
  • ai寫作怎么用?這篇文章教會(huì)你

    ai寫作怎么用?這篇文章教會(huì)你

    在數(shù)字化時(shí)代,寫作已經(jīng)成為了一種不可或缺的技能。無(wú)論是學(xué)術(shù)論文、商業(yè)文案、社交媒體帖子,還是個(gè)人日記、博客文章,我們都需要用到寫作。然而,隨著人工智能技術(shù)的發(fā)展,我們開始使用ai寫作來(lái)完成這些任務(wù)。ai寫作可以幫助人們快速、準(zhǔn)確地完成寫作任務(wù),提高

    2024年02月16日
    瀏覽(25)
  • 一篇文章教會(huì)你什么是Linux進(jìn)程控制

    一篇文章教會(huì)你什么是Linux進(jìn)程控制

    在Linux上一篇文章進(jìn)程概念詳解我們提到了在linux中fork函數(shù)是非常重要的函數(shù),它從已存在進(jìn)程中創(chuàng)建一個(gè)新進(jìn)程。新進(jìn)程為子進(jìn)程,而原進(jìn)程為父進(jìn)程。 返回值 自進(jìn)程中返回0,父進(jìn)程返回子進(jìn)程id,出錯(cuò)返回-1 1.1那么fork創(chuàng)建子進(jìn)程時(shí),操作系統(tǒng)都做了什么呢? 當(dāng)在操作系

    2024年02月13日
    瀏覽(33)
  • docker從安裝到部署項(xiàng)目,一篇文章教會(huì)你

    docker從安裝到部署項(xiàng)目,一篇文章教會(huì)你

    首先看下 Docker 圖標(biāo): 一條小鯨魚上面有些集裝箱,比較形象的說(shuō)明了 Docker 的特點(diǎn),以后見到這個(gè)圖標(biāo)等同見到了 Docker 1. Docker 是一個(gè)開源的應(yīng)用容器引擎,它基于 Go 語(yǔ)言開發(fā),并遵從 Apache2.0 開源協(xié)議 2. 使用 Docker 可以讓開發(fā)者封裝他們的應(yīng)用以及依賴包到一個(gè)可移植的

    2024年02月08日
    瀏覽(25)
  • 一篇文章教會(huì)你如何編寫一個(gè)簡(jiǎn)單的Shell腳本

    一篇文章教會(huì)你如何編寫一個(gè)簡(jiǎn)單的Shell腳本

    Shell腳本概念 Shell 腳本是一種用于自動(dòng)化執(zhí)行一系列命令和操作的腳本文件。它使用的是 Shell 解釋器(如 Bash、Korn Shell、Zsh 等)來(lái)解釋和執(zhí)行其中的命令。Shell 腳本通常用于編寫簡(jiǎn)單的任務(wù)和工作流程,可以幫助我們進(jìn)行系統(tǒng)管理、批量處理、自動(dòng)化部署等任務(wù)。 以.sh后綴

    2024年02月10日
    瀏覽(30)
  • Vue中的Pinia狀態(tài)管理工具 | 一篇文章教會(huì)你全部使用細(xì)節(jié)

    Vue中的Pinia狀態(tài)管理工具 | 一篇文章教會(huì)你全部使用細(xì)節(jié)

    Pinia(發(fā)音為/pi?nj?/,如英語(yǔ)中的“peenya”)是最接近pi?a(西班牙語(yǔ)中的菠蘿)的詞 ; Pinia開始于大概2019年,最初是 作為一個(gè)實(shí)驗(yàn)為Vue重新設(shè)計(jì)狀態(tài)管理 ,讓它用起來(lái)適合組合式API(Composition API)。 從那時(shí)到現(xiàn)在,最初的設(shè)計(jì)原則依然是相同的,并且目前同時(shí)兼容Vue2、

    2024年02月11日
    瀏覽(23)
  • 一篇文章教會(huì)你一個(gè)優(yōu)秀的程序員如何維護(hù)好自己的電腦

    一篇文章教會(huì)你一個(gè)優(yōu)秀的程序員如何維護(hù)好自己的電腦

    我認(rèn)為程序員的筆記本電腦可以根據(jù)不同的特點(diǎn)和用途分為幾類 這里介紹的都是些筆記本 以下是一些常見的分類和它們的特點(diǎn): 輕薄便攜筆記本(Ultrabooks) 優(yōu)點(diǎn): 便攜性 :輕薄設(shè)計(jì)和輕便重量,適合在不同地方工作。 性能 :雖然不如游戲筆記本那樣強(qiáng)大,但在性能和續(xù)

    2024年02月14日
    瀏覽(19)
  • 一篇文章教會(huì)你寫一個(gè)貪吃蛇小游戲(純C語(yǔ)言)

    一篇文章教會(huì)你寫一個(gè)貪吃蛇小游戲(純C語(yǔ)言)

    實(shí)現(xiàn)基本的功能 : ? 貪吃蛇地圖繪制 ? 蛇吃?物的功能(上、下、左、右?向鍵控制蛇的動(dòng)作) ? 蛇撞墻死亡 ? 蛇撞??死亡 ? 計(jì)算得分 ? 蛇?加速、減速 ? 暫停游戲 Win32 API是一套由Microsoft提供的應(yīng)用程序編程接口,用于開發(fā)Windows平臺(tái)上的應(yīng)用程序。它包括了豐

    2024年01月22日
    瀏覽(30)
  • 數(shù)據(jù)結(jié)構(gòu)入門(C語(yǔ)言版)一篇文章教會(huì)你手撕八大排序

    數(shù)據(jù)結(jié)構(gòu)入門(C語(yǔ)言版)一篇文章教會(huì)你手撕八大排序

    排序 :所謂排序,就是使一串記錄,按照其中的某個(gè)或某些的大小,遞增或遞減的排列起來(lái)的操作。 穩(wěn)定性 :假定在待排序的記錄序列中,存在多個(gè)具有相同的的記錄,若經(jīng)過(guò)排序,這些記錄的相對(duì)次序保持不變,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而

    2024年02月01日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包