(C++ STL)list的實現
阿新 • • 發佈:2017-07-21
throw 實現 locate 當前 模板類 spl 會有 splice 重定義
#include <iostream> using namespace std; //採用叠代器和空間配置器所實現的雙向鏈表的基本功能 template<class _Ty,class _A = allocator<_Ty> > //定義模板類 class list //list類 { public: typedef size_t size_type; //類型重定義 protected: struct _Node; //結構體_Node friend struct _Node; //友元 typedef _Node* _Nodeptr; //類型重定義 struct _Node //結構體定義 { _Nodeptr _Next,_Prev; _Ty _Value; }; protected: _A allocator; _Nodeptr _Head; size_type _Size; public: typedef list<_Ty,_A> _Myt; typedef _A allocator_type; //該類型是模板參數A的同義詞 typedef size_t size_type; //正整數類型 typedef ptrdiff_t difference_type; //整數類型 typedef _Ty* pointer; //指向_Ty的指針 typedef const _Ty* const_pointer; //指向_Ty的常量指針 typedef _Ty& reference; //_Ty的引用 typedef const _Ty& const_reference; //_Ty的常量引用 typedef _Ty value_type; //對象類型_Ty class iterator; //訪問list的叠代器 class const_iterator; //訪問list的常量叠代器 friend class const_iterator; //友元 class const_iterator : public _Bidit<_Ty, difference_type> //繼承 { public: //共同擁有成員 _Nodeptr _Mynode() const //指向當前結點 { return (_Ptr); } const_iterator() //默認構造函數 {} const_iterator(_Nodeptr _P):_Ptr(_P) //參數為指針的構造函數 {} const_iterator(const iterator& _X):_Ptr(_X._Ptr) //參數為訪問list的常量叠代器的構造函數 {} const_reference operator*() const //獲取當前_Ty的常量的值 { return _Ptr->_Value; } const_pointer operator->() const //? { return (&**this); } const_iterator& operator++() //前置++的引用 { _Ptr = _Ptr->_Next; return (*this); } const_iterator operator++(int) //後置++的引用 { const_iterator _Tmp = *this; ++*this; return (_Tmp); } const_iterator& operator--() //前置--的引用 { _Ptr = _Ptr->_Prev; return (*this); } const_iterator operator--(int) //後置--的引用 { const_iterator _Tmp = *this; --*this; return (_Tmp); } bool operator==(const const_iterator& _X) const //推斷是否相等 { return (_Ptr == _X._Ptr); } bool operator!=(const const_iterator& _X) const //推斷是否不等 { return (!(*this == _X)); } protected: //保護成員 _Nodeptr _Ptr; }; friend class iterator; //友元 class iterator : public const_iterator //繼承 { public: iterator() //默認構造函數 {} iterator(_Nodeptr _P): const_iterator(_P) //參數為指針的構造函數 {} reference operator*() const //獲取當前_Ty的值 { return _Ptr->_Value; } _Ty* operator->() const //? { return (&**this); } iterator& operator++() //前置++的引用 { _Ptr = _Ptr->_Next; return (*this); } iterator operator++(int) //後置++的引用 { iterator _Tmp = *this; ++*this; return (_Tmp); } iterator& operator--() //前置--的引用 { _Ptr = _Ptr->_Prev; return (*this); } iterator operator--(int) //後置--的引用 { iterator _Tmp = *this; --*this; return (_Tmp); } bool operator==(const iterator& _X) const //推斷是否相等 { return (_Ptr == _X._Ptr); } bool operator!=(const iterator& _X) const //推斷是否不等 { return (!(*this == _X)); } }; public: _Nodeptr _Buynode(_Nodeptr _Narg = 0, _Nodeptr _Parg = 0) //購買結點 { _Nodeptr _S = (_Nodeptr)allocator._Charalloc( //開辟空間 1 * sizeof (_Node)); _S->_Next = _Narg != 0 ? _Narg : _S;; _S->_Prev = _Parg != 0 ? _Parg : _S; return (_S); } void _Freenode(_Nodeptr _S) //釋放空間 { allocator.deallocate(_S, 1); } void _Splice(iterator _P, _Myt& _X, iterator _F, iterator _L) //拼接 { if (allocator == _X.allocator) //將兩個拼接到一起,_X清空 { (_L._Mynode())->_Prev->_Next = _P._Mynode(); (_F._Mynode())->_Prev->_Next = _L._Mynode(); (_P._Mynode())->_Prev->_Next = _F._Mynode(); _Nodeptr _S = (_P._Mynode())->_Prev; (_P._Mynode())->_Prev =(_L._Mynode())->_Prev; (_L._Mynode())->_Prev =(_F._Mynode())->_Prev; (_F._Mynode())->_Prev = _S; } else //將_X中的鏈表數值加入到_P中,_X清空 { insert(_P, _F, _L); _X.erase(_F, _L); } } void _Xran() const //拋出異常 { _THROW(out_of_range, "invalid list<T> subscript"); } public: size_type size() const //長度 { return (_Size); } bool empty() const //判空 { return (size() == 0); } _A get_allocator() const //返回空間配置器 { return (allocator); } void resize(size_type _N, _Ty _X = _Ty()) //又一次定義鏈表長度 { if (size() < _N) { insert(end(), _N - size(), _X); } else { while (_N < size()) { pop_back(); } } } size_type max_size() const //返回鏈表最大可能長度 { return (allocator.max_size()); } reference front() //返回第一個元素的引用 { return (*begin()); } const_reference front() const //返回第一個元素的常量引用 { return (*begin()); } reference back() //返回最後一元素的引用 { return (*(--end())); } const_reference back() const //返回最後一元素的常量引用 { return (*(--end())); } _Myt& operator=(const _Myt& _X) //運算符構造函數 { if (this != &_X) { iterator _F1 = begin(); iterator _L1 = end(); const_iterator _F2 = _X.begin(); const_iterator _L2 = _X.end(); for (; _F1 != _L1 && _F2 != _L2; ++_F1, ++_F2) { *_F1 = *_F2; } erase(_F1, _L1); insert(_L1, _F2, _L2); } return (*this); } public: explicit list():_Head(_Buynode()), _Size(0) //空鏈表 {} explicit list(const _Ty& _V):_Head(_Buynode()), _Size(0) //建一個含_V個默認值是0的元素的鏈表 { insert(begin(),_V,0); } explicit list(size_type _N, const _Ty& _V):_Head(_Buynode()), _Size(0) //建一個含_V個元素的鏈表。值都是_N { insert(begin(),_N, _V); } list(const _Myt& _X): _Head(_Buynode()), _Size(0) //建一個_X的copy鏈表 { insert(begin(), _X.begin(), _X.end()); } list(const _Ty *_F, const _Ty *_L): _Head(_Buynode()), _Size(0) //一個區域的元素[_First, _Last)。 { insert(begin(), _F, _L); } typedef const_iterator _It; list(_It _F, _It _L):_Head(_Buynode()), _Size(0) //常量叠代器 { insert(begin(), _F, _L); } iterator begin() //叠代器第一個節點 { return iterator(_Head->_Next); } const_iterator begin() const //常量叠代器第一個節點 { return (const_iterator(_Head->_Next)); } iterator end() //返回最後一個元素的下一位置的指針 { return iterator(_Head); } const_iterator end() const //返回最後一個元素的下一位置的指針 { return (const_iterator(_Head)); } iterator insert(iterator _P,const _Ty& _X) //在_P之前插入結點 { _Nodeptr _S = _P._Mynode(); _S->_Prev = _Buynode(_S,_S->_Prev); _S = _S->_Prev; _S->_Prev->_Next = _S; _S->_Value = _X; ++_Size; return (iterator(_S)); } void insert(iterator _P,size_type _M, const _Ty& _X) //在_P之前插入_M個_X結點 { for(;0 < _M;--_M) { insert(_P,_X); } } void insert(iterator _P, const _Ty *_F, const _Ty *_L) //在_P之前插入_F到_L的結點 { for (; _F != _L; ++_F) { insert(_P, *_F); } } typedef const_iterator _It; void insert(iterator _P, _It _F, _It _L) //在_P之前插入叠代器_F到_L的結點 { for (; _F != _L; ++_F) { insert(_P, *_F); } } void push_front(const _Ty& _X) //添加一元素到鏈表頭 { insert(begin(), _X); } void pop_front() //刪除鏈表頭的一元素 { erase(begin()); } void push_back(const _Ty& _X) //添加一元素到鏈表尾 { insert(end(), _X); } void pop_back() //刪除鏈表尾的一個元素 { erase(--end()); } void assign(size_type _N, const _Ty& _X) //分配值 { erase(begin(),end()); insert(begin(),_N, _X); } iterator erase(iterator _P) //刪除_P元素 { _Nodeptr _S = (_P++)._Mynode(); _S->_Prev->_Next = _S->_Next; _S->_Next->_Prev = _S->_Prev; _Freenode(_S); --_Size; return (_P); } iterator erase(iterator _F, iterator _L) //刪除_F到_L區域的元素 { while (_F != _L) { erase(_F++); } return (_F); } void clear() //刪除全部元素 { erase(begin(),end()); } void show() //STL源代碼中不存在的函數,自己加的,為了使得測試更方便 { _Nodeptr _P = _Head->_Next; while(_P != _Head) { cout<<_P->_Value<<"-->"; _P = _P->_Next; } cout<<"Over"<<endl; } ~list() //析構函數 { erase(begin(),end()); _Freenode(_Head); _Head = 0, _Size = 0; } public: void swap(_Myt& _X) //交換兩個鏈表 { if (allocator == _X.allocator) //若空間配置器同樣,則僅僅需交換頭結點和大小 { std::swap(_Head, _X._Head); std::swap(_Size, _X._Size); } else //否則將鏈表分別拼接到對方空間中 { iterator _P = begin(); splice(_P, _X); _X.splice(_X.begin(), *this, _P, end()); } } friend void swap(_Myt& _X, _Myt& _Y) //交換兩個鏈表 { _X.swap(_Y); } void splice(iterator _P, _Myt& _X) //對兩個鏈表進行拼接 { if (!_X.empty()) { _Splice(_P, _X, _X.begin(), _X.end()); _Size += _X._Size; _X._Size = 0; } } void splice(iterator _P, _Myt& _X, iterator _F) //對兩個鏈表進行拼接 { iterator _L = _F; if (_P != _F && _P != ++_L) { _Splice(_P, _X, _F, _L); ++_Size; --_X._Size; } } void splice(iterator _P, _Myt& _X, iterator _F, iterator _L) //對兩個鏈表進行拼接 { if (_F != _L) { if (&_X != this) { difference_type _N = 0; _Distance(_F, _L, _N); _Size += _N; _X._Size -= _N; } _Splice(_P, _X, _F, _L); } } void remove(const _Ty& _V) //從鏈表中刪除全部值為_V的元素 { iterator _L = end(); for (iterator _F = begin(); _F != _L; ) { if (*_F == _V) { erase(_F++); } else { ++_F; } } } void unique() //刪除全部反復的元素,以建立一個具有唯一元素值的鏈表, //即鏈表中不會有反復元素 { iterator _F = begin(), _L = end(); if (_F != _L) { for (iterator _M = _F; ++_M != _L; _M = _F) { if (*_F == *_M) { erase(_M); } else { _F = _M; } } } } void merge(_Myt& _X) //把當前鏈表*this和x合並,合並後x為空。 //把x中的元素插入到當前鏈表中。不同意兩個鏈表同樣 { if (&_X != this) { iterator _F1 = begin(), _L1 = end(); iterator _F2 = _X.begin(), _L2 = _X.end(); while (_F1 != _L1 && _F2 != _L2) { if (*_F2 < *_F1) { iterator _Mid2 = _F2; _Splice(_F1, _X, _F2, ++_Mid2); _F2 = _Mid2; } else { ++_F1; } } if (_F2 != _L2) { _Splice(_L1, _X, _F2, _L2); } _Size += _X._Size; _X._Size = 0; } } void reverse() //反轉鏈表中的元素排序 { if (2 <= size()) { iterator _L = end(); for (iterator _F = ++begin(); _F != _L; ) { iterator _M = _F; _Splice(begin(), *this, _M, ++_F); } } } void sort() //依據默認條件對鏈表進行排序? { if (2 <= size()) { const size_t _MAXN = 15; _Myt _X, _A[_MAXN + 1]; size_t _N = 0; while (!empty()) { _X.splice(_X.begin(), *this, begin()); size_t _I; for (_I = 0; _I < _N && !_A[_I].empty(); ++_I) { _A[_I].merge(_X); _A[_I].swap(_X); } if (_I == _MAXN) { _A[_I].merge(_X); } else { _A[_I].swap(_X); if (_I == _N) { ++_N; } } } while (0 < _N) { merge(_A[--_N]); } } } }; template<class _Ty, class _A> inline //模板類推斷是否相等 bool operator==(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (_X.size() == _Y.size() && equal(_X.begin(), _X.end(), _Y.begin())); } template<class _Ty, class _A> inline //模板類推斷是否不等 bool operator!=(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (!(_X == _Y)); } template<class _Ty, class _A> inline //模板類比較鏈表的大小 bool operator<(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (lexicographical_compare(_X.begin(), _X.end(), _Y.begin(), _Y.end())); } template<class _Ty, class _A> inline //模板類比較鏈表的大小_Y < _X bool operator>(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (_Y < _X); } template<class _Ty, class _A> inline //模板類比較鏈表的大小!(_Y < _X) bool operator<=(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (!(_Y < _X)); } template<class _Ty, class _A> inline //模板類比較鏈表的大小!(_X < _Y) bool operator>=(const list<_Ty, _A>& _X, const list<_Ty, _A>& _Y) { return (!(_X < _Y)); } void main() { list<int> c0; //空鏈表 list<int> c1(3); //建一個含三個默認值是0的元素的鏈表 list<int> c2(c1); //建一個c1的copy鏈表 list<int> c3(c1.begin(),c1.end()); //含c1一個區域的元素[_First, _Last)。 int ar[5] = {2,3,4,5,6}; list<int> itlist(ar,ar+5); //用數組賦值 list<int> mylist(3,2); //建一個含三個元素的鏈表,值都是2 mylist.show(); list<int> youlist(3,3); youlist.show(); swap(mylist, youlist); //交換兩個鏈表 mylist.show(); youlist.show(); mylist.swap(youlist); mylist.show(); youlist.show(); list<int>::iterator i1 = itlist.begin(); itlist.splice(i1,mylist); //對兩個鏈表進行結合 itlist.show(); itlist.remove(3); itlist.show(); itlist.unique(); itlist.show(); itlist.merge(mylist); itlist.show(); mylist.show(); itlist.reverse(); itlist.show(); itlist.sort(); itlist.show(); cout<<operator<(itlist,mylist)<<endl; cout<<operator>(itlist,mylist)<<endl; }
(C++ STL)list的實現