日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[STL]List的实现

發布時間:2023/11/30 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [STL]List的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

STL(Standard template Library):c++的標準模板庫


STL是算法和數據結構的軟件框架,它包含了六大組件:算法、迭代器、容器、仿函數、配接器、空間配置器。

迭代器:我們可以把迭代器相當于智能指針,(其實指針也就是一個迭代器)迭代器的類型有:前向迭代器(適用于單鏈表),雙向迭代器(適用于雙向鏈表),隨機迭代器(隨機指向),反向迭代器。

容器:像vector,list,map,set這些都屬于容器。分為序列式容器、關聯式容器及其他容器。

序列式容器:vector、list、deque、string

關聯式容器:set、map、multiset、multimap、hash_set、hash_map、hash_multiset、hash_multimap

其他容器:stack、queue、bitset

仿函數我們之前在冒泡排序的時候用opertor()模擬實現仿函數,來實現排序的升序和降序。

配接器:是一種設計模式,它在原有類型的基礎上擴展成為另一個接口,使原本因為接口不兼容而不能合作的類型可以一起工作。就類似于電源適配器一樣。這里有應用于容器的適配器,應用于仿函數的適配器,應用于配接器的適配器等。

空間配置器:用戶數據都是保存在內存中的,那么內存的申請釋放(malloc/free)工作都是由“空間配置器”承擔的。標準c++中提供了std::allocator類。

我們今天要模擬實現STL中的list:(STL庫中的list是一個雙向循環且帶頭節點的鏈表)

它的節點原型是這樣的:

template<typename T>
struct ListNode
{
?? ?struct ListNode* _next;???????????? //指向下一個節點,即后繼節點
?? ?struct ListNode* _prev;???????????? //指向前一個節點,即前驅節點
?? ?T _data;
?? ?ListNode(const T& data)
?? ??? ?:_data(data)
?? ??? ?,_next(NULL)
?? ??? ?,_prev(NULL)
?? ?{}
};

我們還要用到迭代器,重載了++、--、*、->、==、!=等操作符。主要實現了以下函數:


begin:指向的是第一個元素的位置,即頭節點的下一個位置;

end:指向的是最后一個元素的下一個位置,即頭節點的位置。

如圖:


對于迭代器,還有一個重要的問題就是迭代器失效的問題,當然迭代器失效和指針指向未知區域的道理是一樣的。存在的原因是刪除的時候,在鏈表中,你刪除一個元素后,指針必須修改位置,即保存起來以便找到下一個位置。

舉個例子(迭代器失效):

//list.cpp

#include<iostream> using namespace std; #include<list> #include<algorithm>void Print(list<int> l) {list<int>::iterator it = l.begin();while(it != l.end()){cout<<*it<<" ";++it;} }int main() {list<int> l;l.push_back(1);l.push_back(2);l.push_back(3);l.push_back(4);list<int>::iterator it = l.begin();while(it != l.end()) {if(*it == 2) {l.erase(it); //it刪除后不知道指向哪里}++it;}Print(l);return 0; }

看一下監視窗口:

刪除前:


刪除后:


那么怎么解決迭代器失效問題呢?

只要保存之前it的指向,以便找到下一個指向就ok啦。

list<int>::iterator it = l.begin();while(it != l.end()){if(*it == 2){it = l.erase(it); //此處用it來接收解決迭代器失效問題}++it;}

運行結果



再來說說list,對于庫里邊的list的函數,如push_back,pop_back,push_front,pop_front,Insert,Erase等函數,下面一 一實現一下哦。

//List.h

#pragma once #include<iostream> using namespace std; template<typename T> struct ListNode {struct ListNode* _next;struct ListNode* _prev;T _data;ListNode(const T& data):_data(data),_next(NULL),_prev(NULL){} };template<typename T,typename Ref,typename Ptr> struct ListIterator {typedef ListNode<T> Node;typedef ListIterator<T,T&,T*> Iterator;typedef ListIterator<T,const T&,const T*> ConstIterator;typedef ListIterator<T,Ref,Ptr> Self;ListIterator(Node* node):_node(node){}bool operator==(const Self& x){return _node == x._node;}bool operator!=(const Self& x){return _node != x._node;}Ref operator*(){return (*_node)._data;}Ref operator*() const{return (*_node)._data;}Ptr operator->(){return &(*_node)._data;}Self& operator++(){_node = (*_node)._next;return *this;}Self operator++(int){Self tmp = *this;++(*this);return tmp;}Self& operator--(){_node = (*_node)._prev;return *this;}Self operator--(int){Self tmp = *this;--(*this);return tmp;}Node* _node; };template<typename T> class List { public:typedef ListNode<T> Node;typedef ListIterator<T,T&,T*> Iterator;typedef ListIterator<T,const T&,const T*> ConstIterator; public:Node* BuyNode(const T& data){return new Node(data);} public:List():_head(BuyNode(T())){_head->_next = _head;_head->_prev = _head;} public:Iterator Begin() {return (*_head)._next;}Iterator End(){return _head;}ConstIterator Begin() const{return (*_head)._next;}ConstIterator End() const{return _head;}public:void PushBack(const T& data) //尾插{Node* tmp = BuyNode(data);Node* tail = _head->_prev;tail->_next = tmp;tmp->_prev = tail;tmp->_next = _head;_head->_prev = tmp;}void PopBack() //尾刪{Node* del = _head->_prev;Node* pre = del->_prev;Node* next = del->_next;pre->_next = next;next->_prev = pre;delete del;}void PushFront(const T& data) //頭插{Node* tmp = BuyNode(data);Node* next = _head->_next;_head->_next = tmp;tmp->_prev = _head;tmp->_next = next;next->_prev = tmp;}void PopFront() //頭刪{Node* prev = _head->_prev;Node* next = _head->_next;prev->_next = next;next->_prev = prev;_head = next;}Iterator Insert(Iterator pos,const T& data) //某一個位置前插入{Node* tmp = BuyNode(data);Node* prev = pos._node->_prev;Node* cur = pos._node;prev->_next = tmp;tmp->_prev = prev;tmp->_next = cur;cur->_prev = tmp;return tmp;}ConstIterator Insert(ConstIterator pos,const T& data) //某一個位置前插入{Node* tmp = BuyNode(data);Node* prev = pos._node->_prev;Node* cur = pos._node;prev->_next = tmp;tmp->_prev = prev;tmp->_next = cur;cur->_prev = tmp;return tmp;}Iterator Erase(Iterator pos) //刪除某個位置{assert(pos._node && pos._node != _head); //判斷節點是否為空,或只剩一個頭節點Node* prev = pos._node->_prev;Node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;return Iterator(next); //返回下一個位置}bool Empty() //判斷鏈表是否為空{return _head == _head->_next;}T& Front(){return _head->_next->_data;}T& Back(){return _head->_prev->_data;}const T& Front() const{return _head->_next->_data;}const T& Back() const{return _head->_prev->_data;}void Swap(List<T>& l){swap(_head,l._head);}template<typename InputIterator>void Insert(Iterator pos,InputIterator first,InputIterator last){while(first != last){Insert(pos,*first);++first;}}void Insert(Iterator pos,ConstIterator first,ConstIterator last) //在pos位置插入一段區間{for(;first != last;++first)Insert(pos,*first);} private:Node* _head; };void PrintList(List<int>& l) {List<int>::Iterator it = l.Begin();while(it != l.End()){cout<<*it<<" ";++it;}cout<<endl; }


//List.cpp

#define _CRT_SECURE_NO_WARNINGS 1 #include"List.h" #include<vector> int main() {List<int> l;List<int> l1;const List<int> l3;l.PushBack(1);l.PushBack(2);l.PushBack(3);l.PushBack(4);l.PopBack();PrintList(l);l.PushFront(0);PrintList(l);l.PopFront();l.Insert(l.End(),4);l.Insert(l.Begin(),0);PrintList(l);cout<<"Front:"<<l.Front()<<endl;cout<<"Back:"<<l.Back()<<endl;cout<<"Empty:"<<l.Empty()<<endl;l1.Swap(l);PrintList(l1);PrintList(l);l.PushBack(10);l.PushBack(11);l.PushBack(12);l1.Insert(l1.Begin(),l.Begin(),l.End());PrintList(l1);vector<int> v;v.push_back(55);v.push_back(66);l1.Insert(l1.Begin(),v.begin(),v.end());PrintList(l1);char str[] = {'a','b'};l1.Insert(l1.Begin(),str,str+2);PrintList(l1);return 0; }
運行結果:


總結

以上是生活随笔為你收集整理的[STL]List的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。