1. 程式人生 > >模擬實現簡化版List叠代器&嵌入List

模擬實現簡化版List叠代器&嵌入List

元素 sort 可能 節點數 != ring type 部分 分配

1、叠代器(iterators)概念
(1)叠代器是一種抽象的設計概念,其定義為:提供一種方法,使他能夠按順序遍歷某個聚合體(容器)所包含的所有元素,但又不需要暴露該容器的內部表現方式。

(2)叠代器是一種行為類似智能指針的對象, 而指針最常見的行為就是內 容提領和成員 訪問。 因此叠代器最重要的行為就是對operator*和operator->進行重載。

(3)STL的中心思想在於: 將數據容器和算法分開, 彼此獨立設計, 最後再以一貼膠合劑( iterator) 將它們撮合在一起。STL的叠代器是一個可遍歷STL容器全部或者部分數據。

2、叠代器的使用

以list和vector為例說明

 1 #include<iostream>
 2 #include<vector>
 3 #include<list>
 4 #include<algorithm>
 5 #include<string>
 6 using namespace std;
 7 void Test1()
 8 {
 9 vector<int>v1;
10 v1. push_back(5) ;
11 v1. push_back(4) ;
12 v1. push_back(3) ;
13 v1. push_back(2) ;
14 v1. push_back(1
) ; 15 //叠代器遍歷順序表 16 vector<int>: : iteratorit=v1. begin() ; 17 for(; it! =v1. end() ; ++it) 18 { 19 cout<<*it<<" "; 20 } 21 cout<<endl; 22 // STL的排序算法 23 sort(v1. begin() , v1. end() ) ; 24 it=v1. begin() ; 25 for(; it! =v1. end() ; ++it) 26 { 27 cout<<*it<<" "; 28 }
29 cout<<endl; 30 } 31 voidTest2() 32 { 33 list<string>l1; 34 l1. push_back("xjh") ; 35 l1. push_back("zpw") ; 36 l1. push_back("yb") ; 37 l1. push_back("whb") ; 38 //叠代器遍歷鏈表 39 list<string>: : iteratorit=l1. begin() ; 40 for(; it! =l1. end() ; ++it) 41 { 42 cout<<*it<<" "; 43 } 44 cout<<endl; 45 // STL的替換算法 46 replace(l1. begin() , l1. end() , "xjh", "lcf") ; 47 it=l1. begin() ; 48 for(; it! =l1. end() ; ++it) 49 { 50 cout<<*it<<" "; 51 } 52 cout<<endl; 53 } 54 voidTest3() 55 { 56 list<string>l1; 57 l1. push_back("xjh") ; 58 l1. push_back("zpw") ; 59 l1. push_back("yb") ; 60 l1. push_back("whb") ; 61 //叠代器遍歷鏈表 62 list<string>: : iteratorit=l1. begin() ; 63 for(; it! =l1. end() ; ++it) 64 { 65 cout<<*it<<" "; 66 } 67 cout<<endl; 68 // STL的find算法查找叠代器區間的數據, 並返回找到節點的叠代器 69 it=find(l1. begin() , l1. end() , "yb") ; 70 if(it! =l1. end() ) 71 { 72 cout<<"find success: "<<*it<<endl; 73 //通過叠代器修改節點數據 74 *it="yls"; 75 } 76 it=find(l1. begin() , l1. end() , "yb") ; 77 if(it==l1. end() ) 78 { 79 cout<<"find failed"<<endl; 80 } 81 }

3、什麽是叠代器失效
以vector為例,當我們插入一個元素時它的預分配空間不夠時,它會重新申請一段新空間,將原空間上的元素 復制到新的空間上去,然後再把新加入的元素放到新空間的尾部,以滿足vector元素要求連續存儲的目的。而後原空間會被系統撤銷或征做他用,於是指向原 空間的叠代器就成了類似於“懸垂指針”一樣的東西,指向了一片非法區域。如果使用了這樣的叠代器會導致嚴重的運行時錯誤就變得很自然了。這也是許多書上敘 述vector在insert操作後“可能導致所有叠代器實效”的原因。但是想到這裏我不禁想到vector的erase操作的敘述是“會導致指向刪除元 素和刪除元素之後的叠代器失效”。

 1 void PrintVector(vector<int>&v)
 2 {
 3 vector<int>: : iteratorit=v. begin() ;
 4 for(; it! =v. end() ; ++it)
 5 {
 6 cout<<*it<<" ";
 7 }
 8 cout<<endl;
 9 }
10 void Test1()
11 {
12 vector<int>v1;
13 v1. push_back(1) ;
14 v1. push_back(2) ;
15 v1. push_back(3) ;
16 v1. push_back(4) ;
17 v1. push_back(5) ;
18 v1. push_back(6) ;
19 v1. push_back(7) ;
20 v1. push_back(8) ;
21 PrintVector(v1) ;
22 //叠代器失效
23 vector<int>: : iteratorit=v1. begin() ;
24 while(it! =v1. end() )
25 {
26 if(*it% 2 == 0)
27 it=v1. erase(it) ;
28 else
29 ++it;
30 }
31 PrintVector(v1) ;
32 }
33 void PrintList(list<int>&l1)
34 {
35 list<int>: : iteratorit=l1. begin() ;
36 for(; it! =l1. end() ; ++it)
37 {
38 cout<<*it<<" ";
39 }
40 cout<<endl;
41 }
42 void Test2()
43 {
44 list<int>l1;
45 l1. push_back(1) ;
46 l1. push_back(2) ;
47 l1. push_back(3) ;
48 l1. push_back(4) ;
49 l1. push_back(5) ;
50 l1. push_back(6) ;
51 l1. push_back(7) ;
52 l1. push_back(8) ;
53 PrintList(l1) ;
54 //叠代器失效
55 list<int>: : iteratorit=l1. begin() ;
56 while(it! =l1. end() )
57 {
58 if(*it% 2 == 0)
59 it=l1. erase(it) ;
60 else
61 ++it;
62 }
63 PrintList(l1) ;
64 }
 1 // 1.正向叠代器/反向叠代器
 2 // 2.const/非const
 3 void PrintList(const list<int>& l)
 4 {
 5     list<int>::const_iterator it = l.begin();
 6     while (it != l.end())
 7     {
 8         cout<<*it<<" ";
 9         ++it;
10     }
11     cout<<endl;
12 
13     list<int>::const_reverse_iterator rit = l.rbegin();
14     while (rit != l.rend())
15     {
16         //*rit = 10;
17         cout<<*rit<<" ";
18         ++rit;
19     }
20     cout<<endl;
21 
22     //list<int>::iterator it1 = l.end();
23     //while (it1 != l.begin())
24     //{
25     //    --it1;
26     //    cout<<*it1<<" ";
27     //}
28     //cout<<endl;
29 }

歸納一下叠代器失效的類型:

(1)由於容器元素整體“遷移”導致存放原容器元素的空間不再有效,從而使得指向原空間的叠代器失效。

(2)由於刪除元素使得某些元素次序發生變化使得原本指向某元素的叠代器不再指向希望指向的元素。

4、模擬實現簡化版List叠代器&嵌入List

  1 #pragma once
  2 #include<iostream>
  3 #include<assert.h>
  4 using namespace std;
  5 
  6 template <class T>
  7 struct ItListNode
  8 {
  9     ItListNode<T>* _prev;   // 指向前一個結點的指針
 10     ItListNode<T>* _next;   // 指向後一個結點的指針
 11     T data;    // 結點數據
 12     ItListNode(const T& n)
 13         :_prev(NULL)
 14         ,_next(NULL)
 15         ,data(n)      
 16     {}
 17 };
 18 // List的叠代器
 19 template <class T, class Ref, class Ptr>
 20 class ListIterator
 21 {
 22 public:
 23     typedef ItListNode<T> Node;
 24     Node* node;   // 指向節點的指針
 25     // 這裏Ref、 Ptr模板參數主要是為了方便復用的方式實現const類型的叠代器ConstIterator
 26     typedef ListIterator<T, Ref, Ptr> Self;
 27 
 28     ListIterator(Node* n) 
 29         :node(n)
 30     {}
 31     Ref operator*() {
 32         return node->data;
 33     }
 34     Ptr operator->() {
 35         return &node->data;
 36         //return &(operator*());
 37     }
 38     Self& operator--() {
 39         node = node->_prev;
 40         return *this;
 41     }
 42     Self& operator--(int) {
 43         Self tmp(*this);
 44         node = node->_prev;
 45         return tmp;
 46     }
 47     Self& operator++() {
 48         node = node->_next;
 49         return *this;
 50     }
 51     Self& operator++(int) {
 52         Self tmp(*this);
 53         node = node->_next;
 54         return tmp;
 55     }
 56     bool operator != (const Self& s)const {
 57         return node != s.node;
 58     }
 59 };
 60 
 61 //雙向循環鏈表
 62 template <class T>
 63 class List
 64 {
 65     typedef ItListNode<T> Node;
 66 public:
 67 
 68     // 定義叠代器、 const叠代器
 69     typedef ListIterator<T, T&, T*> Iterator;
 70     typedef ListIterator<T, const T&, const T*> ConIterator;
 71     List() {
 72         Head = BuyNode(T());
 73         Head->_prev = Head;
 74         Head->_next = Head;
 75     }
 76     List(const T& l) 
 77         :Head(BuyNode(T()))
 78     {
 79         Head->_next = Head;
 80         Head->_prev = Head;
 81         ConIterator it = l.Begin();
 82         while (it != l.End()) {
 83             this->PushBack(*it);
 84             ++it;
 85         }
 86     }
 87     List<T>& operator=(const T& l) {
 88         if (*this != &l) {
 89             swap(node, l.node);
 90         }
 91         return *this;
 92     }
 93     ~List() {
 94         Clear();
 95         delete Head;
 96         Head = NULL;
 97     }
 98     Iterator Begin() {
 99         return Iterator(Head->_next);
100     }
101     ConIterator Begin()const {
102         return ConIterator(Head->_next);
103     }
104     Iterator End() {
105         return Iterator(Head);
106     }
107     ConIterator End()const {
108         return ConIterator(Head);
109     }
110     void Clear() {
111         Node*cur = Head->_next;
112         while (cur != Head) {
113             Node* next = cur->_next;
114             delete cur;
115             cur = next;
116         }
117         Head->_next = Head;
118         Head->_prev = Head;
119     }
120     void PushBack(const T& n) {
121         /*Node* tail = Head->_prev;
122         Node* tmp = BuyNode(n);
123         tail->_next = tmp;
124         tmp->_prev = tail;
125         tmp->_next = Head;
126         Head->_prev = tmp;*/
127         Insert(End(), n);
128     }
129     void PopBack() {
130         Erase(--End());
131     }
132     void PushFront(const T& n) {
133         Insert(Begin(), n);
134     }
135     void PopFront() {
136         Erase(Begin());
137     }
138     // 在pos前插入一個節點
139     void Insert(Iterator pos, const T& n) {
140         Node* Next = pos.node;
141         Node* Prev = Next->_prev;
142         Node* Cur = BuyNode(n);
143         Prev->_next = Cur;
144         Cur->_prev = Prev;
145         Cur->_next = Next;
146         Next->_prev = Cur;
147     }
148     // 在pos前插入一個節點
149     Iterator Erase(Iterator pos) {
150         assert(pos.node&&pos.node != Head);
151         Node* Cur = pos.node;
152         Node* Prev = Cur -> _prev;
153         Node* Next = Cur -> _next;
154         delete Cur;
155         Prev->_next = Next;
156         Next->_prev = Prev;
157         return Iterator(Next);
158     }
159     Iterator Find(const T& n) {
160         Iteraptor* it = Begin();
161         while (it != End()) {
162             if (*it == n)
163                 return it;
164         }
165         return End();
166     }
167 
168 protected:
169     Node* BuyNode(const T& n) {
170         return new Node(n);
171     }
172     
173 private:    
174     Node* Head;
175 };
176 
177 // 1.測試List叠代器Iterator
178 void PrintList1(List<int>& l1)
179 {
180     List<int>::Iterator it = l1.Begin();
181     for (; it != l1.End(); ++it)
182     {
183         cout << *it << " ";
184     }
185     cout << endl;
186 }
187 //2.測試List叠代器ConstIterator
188 void PrintMyList(const List<int>& L1) {
189     List<int>::ConIterator it1 = L1.Begin();
190     while (it1 != L1.End()) {
191         cout << *it1 << " ";
192         ++it1;
193     }
194     cout << endl;
195 }
196 int main() {
197     List<int> L1;
198     L1.PushBack(1);
199     L1.PushBack(2);
200     L1.PushBack(3);
201     L1.PushBack(4);
202     PrintMyList(L1);
203 
204     PrintList1(L1);
205     L1.PopBack();
206     PrintMyList(L1);
207 
208     L1.PushFront(4);
209     L1.PushFront(5);
210     L1.PushFront(6);
211     L1.PushFront(7);
212     PrintMyList(L1);
213     L1.PopFront();
214     PrintMyList(L1);
215 
216     getchar();
217     return 0;
218 }

模擬實現簡化版List叠代器&嵌入List