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

Cpp學(xué)習(xí)——list的模擬實(shí)現(xiàn)

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

Cpp學(xué)習(xí)——list的模擬實(shí)現(xiàn),C++基礎(chǔ),學(xué)習(xí),Cpp,學(xué)習(xí)筆記,c++,筆記,list

?

目錄

一,實(shí)現(xiàn)list所需要包含的三個(gè)類

二,三個(gè)類的實(shí)現(xiàn)

1.list_node

2.list類

?3.iterator_list類

三,功能實(shí)現(xiàn)

1.list類里的push_back()

??2.iterator類里的運(yùn)算符重載

3,list類里面的功能函數(shù)

1.insert()

2.erase()函數(shù)

3.clear()與析構(gòu)函數(shù)

4.拷貝構(gòu)造函數(shù)賦值運(yùn)算符重載

5.打印函數(shù)


一,實(shí)現(xiàn)list所需要包含的三個(gè)類

? ? ?因?yàn)閘ist是一個(gè)帶頭雙向循環(huán)鏈表。所以list的實(shí)現(xiàn)會(huì)比較的復(fù)雜一些??偟脕?lái)說(shuō),實(shí)現(xiàn)一個(gè)雙向帶頭循環(huán)鏈表需要構(gòu)造三個(gè)類。1.list類,2.list_node類,3.list_iterator類。前兩個(gè)類相信大家會(huì)比較的熟悉。第三個(gè)類大家會(huì)比較不熟悉,因?yàn)樗且粋€(gè)迭代器的類。也就是說(shuō)這個(gè)類是迭代器的封裝。它的實(shí)現(xiàn)很有價(jià)值,因?yàn)樗茏屛覀冊(cè)谑褂胠ist時(shí)也可以像之前的數(shù)據(jù)結(jié)構(gòu)一樣方便。

二,三個(gè)類的實(shí)現(xiàn)

1.list_node

?這首先要實(shí)現(xiàn)的便是節(jié)點(diǎn)類。這個(gè)類是最容易實(shí)現(xiàn)的。這個(gè)類的作用便是給要產(chǎn)生的節(jié)點(diǎn)畫一個(gè)圖,定義一下這個(gè)節(jié)點(diǎn)的結(jié)構(gòu)和類型。代碼如下:

template<class T>//模板
  	struct list_node
	{
		list_node(const T& val =T()//匿名對(duì)象 )//構(gòu)造函數(shù)起初始化的作用
			:val(val)
			, prev(nullptr)
			, next(nullptr)
		{}

		T val;
		list_node<T>* prev;
		list_node<T>* next;
	};

現(xiàn)在你看到了,這個(gè)節(jié)點(diǎn)的結(jié)構(gòu)便是這樣。其實(shí)這與之前實(shí)現(xiàn)的那個(gè)帶頭雙向循環(huán)鏈表的結(jié)構(gòu)差不多。不過(guò),在cpp中引入了模板的概念,所以這個(gè)節(jié)點(diǎn)便可以調(diào)用模板參數(shù)來(lái)進(jìn)行泛化。

2.list類

list類的定義可太簡(jiǎn)單了。list的成員變量只有一個(gè)參數(shù),便是_head。這是哨兵位的頭節(jié)點(diǎn)。當(dāng)然還有一個(gè)無(wú)參的構(gòu)造函數(shù)和一個(gè)功能函數(shù)。代碼如下:

template<class T>
	class list
	{ public:
		typedef list_node<T> Node;
		void empty()//初始化功能函數(shù)。
		{
			_head = new Node;
			_head->prev = _head;
			_head->next = _head;
		}
		list()//構(gòu)造函數(shù)
		{
			empty();
		}

	private:
		Node* _head;

	};

當(dāng)然,這里的list類也是要用模板來(lái)進(jìn)行泛化的。

?3.iterator_list類

這個(gè)類就算是比較復(fù)雜的一個(gè)類了。因?yàn)榈饕獙?shí)現(xiàn)兩種重載版本:1.普通版本。2.const版本。所以迭代器類的模板參數(shù)會(huì)有三個(gè):

template <class T, class Ref, class ptr>

這三個(gè)模板參數(shù)會(huì)重載兩種版本的三個(gè)參數(shù):T對(duì)象,T&,T指針類型。在這個(gè)類里面也只有一個(gè)成員:_node。類型與list類里面的成員類型相同。該類代碼如下:

template <class T, class Ref, class ptr>
	struct iterator_list
	{
		typedef list_node<T> Node;
		iterator_list(Node* node)
			:_node(node)
		{}

		Node* _node;

	};

三,功能實(shí)現(xiàn)

1.list類里的push_back()

首先來(lái)實(shí)現(xiàn)一個(gè)push_back()函數(shù),這個(gè)函數(shù)的作用便是實(shí)現(xiàn)尾插數(shù)據(jù)。邏輯十分簡(jiǎn)單,代碼如下:

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

			tail->next = newnode;
			newnode->prev = tail;
			newnode->next = _head;
			_head->prev = newnode;
		}
		

寫完這個(gè)以后,我便想要通過(guò)顯示list里的數(shù)據(jù)來(lái)驗(yàn)證答案,但是很顯然,我們做不到。因?yàn)閘ist是一個(gè)自定義的類。但是我們有辦法,所以我們便可以通過(guò)iterator來(lái)達(dá)到這個(gè)目的。所以我們必須在iterator類里面實(shí)現(xiàn)幾個(gè)運(yùn)算符重載。

??2.iterator類里的運(yùn)算符重載

首先先實(shí)先這三個(gè)運(yùn)算符重載:1.*,2.++,3.!=

代碼如下:

        Ref operator *()//Ref代表T&
		{
			return _node->val;
		}

		self operator++()
		{
			_node = _node->next;
			return *this;
		}

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

然后再在list類里面實(shí)現(xiàn)begin()與end()函數(shù)之后便可以實(shí)現(xiàn)范圍for的使用了,end與begin代碼如下:

       //實(shí)現(xiàn)兩個(gè)版本的begin與end
        iterator begin()
		{
			return _head->next;
		}

		iterator end()
		{
			return _head;
		}

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

		const_iterator end()const
		{
			return _head;
		}

在實(shí)現(xiàn)了上面的代碼以后,為了讓迭代器的功能更加全面,那我們?cè)賹?shí)現(xiàn)幾個(gè)函數(shù)重載。再iterator_list里面的全部運(yùn)算符重載如下:

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

		self& operator++()//前置++
		{
			_node = _node->next;
			return *this;
		}

		self operator++(int)//后置++
		{
			Node* tmp(*this);
			_node = _node->next;
			return tmp;
		}

		self& operator --()//前置--
		{
			_node = _node->prev;
			return *this;
		}

		self operator--(int)//后置--
		{
			Node* tmp(*this);
			_node = _node->prev;
			return tmp;
		}

		bool operator!=(const self& it)//若用引用便要加上const
		{
			return _node != it._node;
		}

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

		self& operator+(int n)
		{
			while (n)
			{
				_node = _node->next;
				n--;
			}
			return *this;
		}

		ptr operator->()//箭頭解引用
		{
			return &_node->val;
		}

在實(shí)現(xiàn)了這些運(yùn)算符重載以后,list類里面的功能函數(shù)便好寫了許多。

3,list類里面的功能函數(shù)

1.insert()

這個(gè)函數(shù)實(shí)現(xiàn)的功能便是在pos位置之前插入一個(gè)新的節(jié)點(diǎn)。這個(gè)pos的類型是迭代器類型。在list類里邊的迭代器重定義為:

typedef iterator_list<T, T& ,T*> iterator;
typedef iterator_list<T, const T&, const T*> const_iterator;

我們只需要關(guān)注第一個(gè)迭代器即可,因?yàn)榈诙€(gè)迭代器修飾的對(duì)象是不可以修改的。所以insert的實(shí)現(xiàn)代碼如下:

	iterator insert(iterator pos, const T& x)//在pos位置之前插入新節(jié)點(diǎn)
		{
			Node* newnode = new Node(x);
			Node* prev = pos._node->prev;

			prev->next = newnode;
			newnode->prev = prev;
			newnode->next = pos._node;
			pos._node->prev = newnode;

			return pos._node->prev;//防止迭代器失效,所以返回pos的前一個(gè)位置
			
		}

檢驗(yàn)一下,檢驗(yàn)代碼如下:

void test_list2()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		l1.push_back(5);

		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;

		l1.insert(l1.begin(), 9);
		l1.insert(l1.end(), 99);

		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;

	}

結(jié)果:正確

Cpp學(xué)習(xí)——list的模擬實(shí)現(xiàn),C++基礎(chǔ),學(xué)習(xí),Cpp,學(xué)習(xí)筆記,c++,筆記,list

?在實(shí)現(xiàn)了insert()函數(shù)以后便可以復(fù)用實(shí)現(xiàn)push_back()與push_front()。代碼如下:

        void push_back(const T& val)
		{
			insert(begin(), val);
		}

		void push_front(const T& val)
		{
			insert(end(), val);
		}
2.erase()函數(shù)

erase()函數(shù)實(shí)現(xiàn)的功能便是傳入一個(gè)位置,然后將該位置上的節(jié)點(diǎn)刪除掉。代碼實(shí)現(xiàn)如下:

       iterator erase(iterator pos)
		{
			Node* prev = pos._node->prev;
			Node* next = pos._node->next;
			Node* cur = pos._node;

			delete cur;

			prev->next = next;
			next->prev = prev;

			return iterator(next);//返回新的迭代器

		}

復(fù)用erase實(shí)現(xiàn)尾刪與頭刪,代碼如下:

?
        void pop_back()
		{
			erase(--end());//尾巴是--end()的位置
		}

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

?

實(shí)驗(yàn)代碼:

void test_list3()
	{
		list<int> l1;
		l1.push_back(1);
		l1.push_back(2);
		l1.push_back(3);
		l1.push_back(4);
		l1.push_back(5);

		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;

		l1.insert(l1.begin(), 9);
		l1.insert(l1.end(), 99);

		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;


		l1.pop_back();
		l1.pop_front();
	   

		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;


	}

結(jié)果:正確

Cpp學(xué)習(xí)——list的模擬實(shí)現(xiàn),C++基礎(chǔ),學(xué)習(xí),Cpp,學(xué)習(xí)筆記,c++,筆記,list

3.clear()與析構(gòu)函數(shù)

實(shí)現(xiàn)了erase()函數(shù)以后再接再厲,接著復(fù)用實(shí)現(xiàn)clear函數(shù),代碼如下:

        void clear()
		{
			iterator it = begin();
			while (it != end())
			{
				it = erase(it);//erase()每次都會(huì)返回下一個(gè)位置
			
			}
		}

從上面代碼的邏輯便可以看出clear()函數(shù)是不會(huì)刪除掉頭節(jié)點(diǎn)的。但是析構(gòu)函數(shù)需要。于是復(fù)用clear()函數(shù)后析構(gòu)函數(shù)代碼如下:

       ~list()
		{
			clear();
			delete _head;
		}
4.拷貝構(gòu)造函數(shù)賦值運(yùn)算符重載

拷貝構(gòu)造函數(shù)實(shí)現(xiàn)過(guò)程大概分三步,首先new出來(lái)一個(gè)空間。然后再?gòu)?fù)用push_back()函數(shù)將要賦值的數(shù)據(jù)拷貝到新節(jié)點(diǎn)內(nèi)。實(shí)現(xiàn)代碼如下:

	list(const list<T>& l1)
		{
			empty();

			for (auto e : l1)
			{
				push_back(e);
			}
		}

實(shí)現(xiàn)了拷貝構(gòu)造以后,按照慣例,賦值也要被安排上了。賦值運(yùn)算符重載實(shí)現(xiàn)代碼如下:

     list<T>& operator =( list<T>& l1)
		{
			if (this!= &l1)
			{
				clear();
				for (auto e : l1)
				{
					push_back(e);
				}
			}
			return *this;
		}

這是一個(gè)傳統(tǒng)寫法的運(yùn)算符重載。如果想要更加精簡(jiǎn)可以寫成現(xiàn)代寫法,代碼如下:

        void swap( list<T>& l1)//別加const
		{
			std::swap(_head, l1._head);//記得這個(gè)swap是std里面的swap
		}

		list<T>& operator=(list<T> l1)
		{
			if (this != &l1)
			{
				swap(l1);
			}

			return *this;
		}
5.打印函數(shù)

在這里,我們每次打印一個(gè)list對(duì)象時(shí)會(huì)很麻煩,每次都要用范圍for來(lái)實(shí)現(xiàn)打印的功能。為了偷懶,我就想實(shí)現(xiàn)一個(gè)打印函數(shù)print來(lái)實(shí)現(xiàn)打印功能。實(shí)現(xiàn)代碼如下:

template<class T>
	void print(list<T>& l1)
	{
		typename list<T>::iterator it = l1.begin();//這里要用typename為前綴來(lái)告訴編譯器等list<T>實(shí)例化以后再來(lái)執(zhí)行這條語(yǔ)句
		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;

	}

但是上面的代碼針對(duì)的類型時(shí)list類的泛型,如果想要實(shí)現(xiàn)能加載更多容器的print()函數(shù)那就得改一下類型,改為如下代碼:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-659626.html

template <class Contains>
	void print(Contains& l1)
	{
		typename Contains::iterator it = l1.begin();
		for (auto e : l1)
		{
			cout << e << " ";
		}
		cout << endl;
	}

到了這里,關(guān)于Cpp學(xué)習(xí)——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)文章

  • vector類模擬實(shí)現(xiàn)(c++)(學(xué)習(xí)筆記)

    vector類模擬實(shí)現(xiàn)(c++)(學(xué)習(xí)筆記)

    基本框架: vector的大致形狀如下:黃色代表每天滿的地方。 使用初始化列表實(shí)現(xiàn)一個(gè)簡(jiǎn)單的無(wú)參構(gòu)造函數(shù)。 記住要帶[]即可。 因?yàn)閜ush_back涉及到擴(kuò)容函數(shù),需要實(shí)現(xiàn)reserve()。 如下示例: 問(wèn)題1:_finish賦值出錯(cuò),出bug了,是因?yàn)閟ize()函數(shù),調(diào)用了空指針,導(dǎo)致報(bào)錯(cuò)。 改正:

    2024年02月05日
    瀏覽(17)
  • 【ESP32最全學(xué)習(xí)筆記(基礎(chǔ)篇)——7.ESP32 ADC – 使用 Arduino IDE 讀取模擬值】

    關(guān)于本教程: 1.ESP32簡(jiǎn)介???????????????????????????????????????????????????????????????? 2.ESP32 Arduino 集成開(kāi)發(fā)環(huán)境 3.VS 代碼和 PlatformIO 4.ESP32 引腳 5.ESP32 輸入輸出 6.ESP32 脈寬調(diào)制 7.ESP32 模擬輸入 ? 8.ESP32 中斷定時(shí)器 9 .ESP32 深度睡眠 ESP32 網(wǎng)絡(luò)

    2023年04月15日
    瀏覽(41)
  • 【C++模擬實(shí)現(xiàn)】list的模擬實(shí)現(xiàn)

    作者:愛(ài)寫代碼的剛子 時(shí)間:2023.9.3 前言:本篇博客關(guān)于list的模擬實(shí)現(xiàn)和模擬實(shí)現(xiàn)中遇到的問(wèn)題 list模擬實(shí)現(xiàn)的部分代碼 list模擬實(shí)現(xiàn)中的要點(diǎn) const_iterator的實(shí)現(xiàn) 我們選擇使用模版參數(shù),復(fù)用iterator的類,設(shè)置三個(gè)模版參數(shù): templateclass T,class Ref,class Ptr 并且 typedef __list_iter

    2024年02月09日
    瀏覽(25)
  • list(模擬實(shí)現(xiàn))

    目錄 list概念 list的使用 list的構(gòu)造 list iterator的使用 list capacity list element access list modifiers list的迭代器失效 list的模擬實(shí)現(xiàn) list與vector的對(duì)比 list是可以在常數(shù)范圍內(nèi)在任意位置進(jìn)行插入和刪除的序列式容器,并且該容器可以前后雙向迭代。 list的底層是雙向鏈表結(jié)構(gòu),雙向鏈表

    2024年02月16日
    瀏覽(18)
  • C++ list模擬實(shí)現(xiàn)

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

    源碼中的list實(shí)現(xiàn)為 帶頭雙向鏈表 ? list類的對(duì)象有兩個(gè)成員:指向頭結(jié)點(diǎn)的指針_head,統(tǒng)計(jì)數(shù)據(jù)個(gè)數(shù)的_size 在模擬實(shí)現(xiàn)list之前,需要先模擬實(shí)現(xiàn) 結(jié)點(diǎn)類,迭代器類 結(jié)點(diǎn)類:三個(gè)成員,_data _prev _next , 實(shí)現(xiàn)成struct (也是類,不過(guò)與class不同的是,它的成員都是公開(kāi)的,都可以

    2024年02月11日
    瀏覽(25)
  • C++list模擬實(shí)現(xiàn)

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

    自我名言 : 只有努力,才能追逐夢(mèng)想,只有努力,才不會(huì)欺騙自己。 喜歡的點(diǎn)贊,收藏,關(guān)注一下把! 庫(kù)里面的list類模板,實(shí)現(xiàn)的是帶頭雙向循環(huán)鏈表。這里我們和庫(kù)實(shí)現(xiàn)的是一樣的。 這里鏈表結(jié)點(diǎn)實(shí)現(xiàn)的是一個(gè)模板,因?yàn)槲覀儾⒉恢绖e人想在結(jié)點(diǎn)里放什么數(shù)據(jù)。 其次

    2024年02月07日
    瀏覽(12)
  • C++ list 模擬實(shí)現(xiàn)

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

    ? 目錄 1.?基本結(jié)構(gòu)的實(shí)現(xiàn) 2.??list() 3. void push_back(const T val) 4.?非 const 迭代器 4.1?基本結(jié)構(gòu)? 4.2?構(gòu)造函數(shù)? 4.3?T operator*() 4.4??__list_iterator operator++() 4.5 bool operator!=(const __list_iterator?it) 4.6 T* operator-() 5. const?迭代器? 6.?begin() ?end() ?編輯 7.?iterator insert(iterator pos, const T v

    2024年02月08日
    瀏覽(24)
  • 【C++】list模擬實(shí)現(xiàn)

    【C++】list模擬實(shí)現(xiàn)

    個(gè)人主頁(yè) : zxctscl 如有轉(zhuǎn)載請(qǐng)先通知 在前面一篇博客中分享了list的相關(guān)介紹 【C++】list介紹,這次來(lái)模擬實(shí)現(xiàn)一下list。 成員變量: 無(wú)參構(gòu)造: 插入: 在庫(kù)里面定義節(jié)點(diǎn)需要全部公有時(shí)用到的就是struct: 這里我們也用相同方法自己定義出一個(gè)節(jié)點(diǎn): 然后在寫list類時(shí)候就要

    2024年04月11日
    瀏覽(23)
  • list的模擬實(shí)現(xiàn)

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

    前言 ? ? ? ? list 是 STL 中重要的容器,了解它的原理對(duì)于我們掌握它是有很多的幫助的,一般 list 和 vector 都是一起來(lái)使用的,因?yàn)樗鼈兊膬?yōu)缺點(diǎn)不同,剛好可以互補(bǔ)。list的優(yōu)點(diǎn)是任意位置的插入和刪除都很快,它的缺點(diǎn)是不支持隨機(jī)訪問(wèn),而vector的優(yōu)點(diǎn)是支持隨機(jī)訪問(wèn),

    2024年02月09日
    瀏覽(15)
  • 【STL】list的模擬實(shí)現(xiàn)

    【STL】list的模擬實(shí)現(xiàn)

    目錄 前言 結(jié)構(gòu)解析 默認(rèn)成員函數(shù) 構(gòu)造函數(shù) 拷貝構(gòu)造 賦值重載 析構(gòu)函數(shù) 迭代器 const迭代器 數(shù)據(jù)修改 insert erase 尾插尾刪頭插頭刪 容量查詢 源碼? ??list之所以擺脫了單鏈表尾插麻煩,只能單向訪問(wèn)等缺點(diǎn),正是因?yàn)槠湓诮Y(jié)構(gòu)上升級(jí)成了帶頭雙向循環(huán)鏈表。不僅如此,lis

    2024年02月06日
    瀏覽(26)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包