STL之list学习(2)(list代码实现)(只剩最后一步,迭代器升级!!)
《數(shù)據(jù)結(jié)構(gòu)與算法分析》書本代碼,書本的代碼內(nèi)容居然分開超多部分,看起來真得很痛苦,之前看這一章老是看到這一部分就不想看,list的實(shí)現(xiàn)本來就麻煩,而且分開,所以一直都是跳開。不過通過認(rèn)真分析,再敲代碼,一邊敲代碼一邊理解,收獲真得很不錯(cuò),而且這本書的習(xí)題很贊,有很多題都是要你在程序上完善,修改、添加。好了,體外話說完。
PS:這次加了兩張圖片!(《數(shù)據(jù)結(jié)構(gòu)與算法分析》的圖片,方便理解)。
PS:添加了習(xí)題3.15和3.16.
見:http://www.cnblogs.com/alan-forever/archive/2012/10/15/2725290.html
看了這些代碼有數(shù)遍之后,覺得將const_iterator、iterator迭代器設(shè)置為公有嵌套類是很不錯(cuò)的。因?yàn)閏onst_iterator、iterator迭代器,不同于Vector的迭代器,Vector的迭代器只是簡單指針而這個(gè)List的迭代器的基本實(shí)現(xiàn)要比Vector的復(fù)雜。Vector原理是數(shù)組,數(shù)組本來就是指針,里面的元素儲(chǔ)存在連續(xù)的地址里面,(++)(--)操作符不用重載就可以實(shí)現(xiàn)功能。而List不一樣除了儲(chǔ)存元素,它還有前指針、后指針,它是通過這些指針連接它之前及之后的Node(結(jié)點(diǎn)),因此List里面的元素在物理上是不連續(xù)的,所以要實(shí)現(xiàn)它的迭代器功能就需要定義一個(gè)類,并且重載操作符。(個(gè)人愚見)
1 #include<iostream> 2 using namespace std; 3 4 template <typename Object> 5 class List 6 { 7 private: 8 struct Node //私有嵌套結(jié)構(gòu)體。 9 { 10 Object data; 11 Node *prev; 12 Node *next; 13 14 Node( const Object & d = Object( ), Node *p = NULL, Node *n = NULL ) : data( d ), prev( p ), next( n ) { } 15 }; /*Node結(jié)構(gòu)體包含存儲(chǔ)的項(xiàng)、指向Node之前及之后的指針和一個(gè)構(gòu)造函數(shù)。都是公有的數(shù)據(jù)成員*/ 16 public: 17 class const_iterator //公有嵌套類。 18 { 19 public: 20 const_iterator( ) : current ( NULL ) { } //const_iterator類的無參數(shù)構(gòu)造函數(shù)。 21 22 const Object & operator* ( ) const 23 { 24 return retrieve( ); 25 } //解引用操作符的重載。調(diào)用retrieve函數(shù)。 26 27 const_iterator & operator++ ( ) 28 { 29 current = current->next; 30 return *this; 31 } 32 //前自增操作符重載。當(dāng)前的結(jié)點(diǎn)直接變成它指向的下一個(gè)結(jié)點(diǎn),并返回。 33 const_iterator operator++ ( int ) 34 { 35 const_iterator old = *this; 36 ++( *this ); 37 return old; 38 } 39 //后自增操作符重載。要先存儲(chǔ)當(dāng)前的結(jié)點(diǎn),再調(diào)用前自增操作符,最后返回儲(chǔ)存的結(jié)點(diǎn)。 40 const_iterator operator-- ( ) 41 { 42 current = current->prev; 43 return *this; 44 } 45 //前自減操作符重載。當(dāng)前的結(jié)點(diǎn)直接直接變成它指向的前一個(gè)結(jié)點(diǎn),并返回。 46 const_iterator operator-- ( int ) 47 { 48 const_iterator old = *this; 49 --( *this ); 50 return old; 51 } 52 //后自減操作符重載。先儲(chǔ)存當(dāng)前結(jié)點(diǎn),再調(diào)用前自減操作符,最后返回儲(chǔ)存的結(jié)點(diǎn)。 53 const_iterator operator+( int k ) const 54 { 55 const_iterator itr = *this; 56 for( int i = 1; i <= k; ++i ) 57 itr.current = itr.current->next; 58 return itr; 59 } 60 61 bool operator== ( const const_iterator & rhs ) const 62 { 63 return current == rhs.current; 64 } 65 bool operator != ( const const_iterator & rhs ) const 66 { 67 return !( *this == rhs ); 68 } 69 //(==)(!=)操作符的重載。 70 protected: 71 Node *current; 72 73 Object & retrieve( ) const 74 { 75 return current->data; 76 } //返回當(dāng)前結(jié)點(diǎn)儲(chǔ)存的元素。 77 78 const_iterator( Node *p ) : current( p ) { } //const_iterator的構(gòu)造函數(shù),儲(chǔ)存當(dāng)前結(jié)點(diǎn) 79 80 friend class List<Object>; //友元函數(shù),可以讓List調(diào)用const_iterator的函數(shù)。 81 }; 82 83 class iterator//安裝書本的代碼,這個(gè)應(yīng)該是const_iterator的派生類,因?yàn)楹芏嗖僮鞫家粯?#xff0c;但是老是報(bào)錯(cuò),也只好這樣寫。 84 { 85 public: 86 iterator( ) : current ( NULL ) { } 87 88 Object & operator* ( ) 89 { 90 return retrieve( ); 91 } 92 93 iterator & operator++ ( ) 94 { 95 current = current->next; 96 return *this; 97 } 98 99 iterator operator++ ( int ) 100 { 101 iterator old = *this; 102 ++( *this ); 103 return old; 104 } 105 iterator operator-- ( ) 106 { 107 current = current->prev; 108 return *this; 109 } 110 iterator operator-- ( int ) 111 { 112 iterator old = *this; 113 --( *this ); 114 return old; 115 } 116 117 iterator operator+( int k ) 118 { 119 iterator itr = *this; 120 for( int i = 1; i <= k; ++i ) 121 itr.current = itr.current->next; 122 return itr; 123 } 124 125 126 bool operator== ( const iterator & rhs ) const 127 { 128 return current == rhs.current; 129 } 130 bool operator != ( const iterator & rhs ) const 131 { 132 return !( *this == rhs ); 133 } 134 135 protected: 136 Node *current; 137 138 Object & retrieve( ) const 139 { 140 return current->data; 141 } 142 143 iterator( Node *p ) : current( p ) { } 144 145 friend class List<Object>; 146 }; 147 148 class const_reverse_iterator 149 { 150 public: 151 const_reverse_iterator( ) : current( NULL ) { } 152 153 const Object & operator* ( ) const 154 { 155 return retrieve( ); 156 } 157 158 const_reverse_iterator & operator++ ( ) 159 { 160 current = current->prev; 161 return * this; 162 } 163 164 const_reverse_iterator operator++ ( int ) 165 { 166 const_reverse_iterator old = *this; 167 ++( *this ); 168 return old; 169 } 170 171 const_reverse_iterator & operator-- ( ) 172 { 173 current = current->next; 174 return * this; 175 } 176 177 const_reverse_iterator operator-- ( int ) 178 { 179 const_reverse_iterator old = *this; 180 ++( *this ); 181 return old; 182 } 183 184 bool operator== ( const const_reverse_iterator & rhs ) const 185 { 186 return current == rhs.current; 187 } 188 189 bool operator!= ( const const_reverse_iterator & rhs ) const 190 { 191 return !( *this == rhs ); 192 } 193 194 private: 195 Node * current; 196 197 Object & retrieve( ) const 198 { 199 return current->data; 200 } 201 202 const_reverse_iterator( Node * p ) : current( p ) { } 203 204 friend class List<Object>; 205 }; 206 //逆向迭代器 207 208 class reverse_iterator 209 { 210 public: 211 reverse_iterator( ) : current( NULL ) { } 212 213 const Object & operator* ( ) const 214 { 215 return retrieve( ); 216 } 217 218 reverse_iterator & operator++ ( ) 219 { 220 current = current->prev; 221 return * this; 222 } 223 224 reverse_iterator operator++ ( int ) 225 { 226 reverse_iterator old = *this; 227 ++( *this ); 228 return old; 229 } 230 231 const_reverse_iterator & operator-- ( ) 232 { 233 current = current->next; 234 return * this; 235 } 236 237 reverse_iterator operator-- ( int ) 238 { 239 const_reverse_iterator old = *this; 240 --( *this ); 241 return old; 242 } 243 244 bool operator== ( const reverse_iterator & rhs ) const 245 { 246 return current == rhs.current; 247 } 248 249 bool operator!= ( const reverse_iterator & rhs ) const 250 { 251 return !( *this == rhs ); 252 } 253 254 private: 255 Node * current; 256 257 Object & retrieve( ) const 258 { 259 return current->data; 260 } 261 262 reverse_iterator( Node * p ) : current( p ) { } 263 264 friend class List<Object>; 265 }; 266 //逆向迭代器 267 268 public: 269 List() 270 { 271 init( ); 272 } 273 //List的構(gòu)造函數(shù),調(diào)用私有成員函數(shù)init。生成一個(gè)默認(rèn)鏈表(有表頭、表尾結(jié)點(diǎn)的鏈表)。 274 ~List() 275 { 276 clear(); 277 delete head; 278 delete tail; 279 } 280 //析構(gòu)函數(shù),要將里面都東西刪除了。 281 List( const List & rhs) 282 { 283 init( ); 284 *this = rhs; 285 } 286 //復(fù)制構(gòu)造函數(shù)。 287 const List & operator= ( const List & rhs) 288 { 289 if( this == &rhs) 290 return *this; 291 clear(); 292 for( const_iterator itr = rhs.begin(); itr != rhs.end(); ++itr) 293 push_back( *itr ); 294 return *this; 295 } 296 //(=)操作符重載。 297 iterator begin( ) 298 { 299 return iterator( head->next ); 300 } 301 const_iterator begin( ) const 302 { 303 return const_iterator( head->next ); 304 } //begin迭代器。不是返回head。head只是表頭,不是儲(chǔ)存第一個(gè)元素的結(jié)點(diǎn)。 305 iterator end( ) 306 { 307 return iterator( tail ); 308 } 309 const_iterator end( ) const 310 { 311 return const_iterator( tail ); 312 } 313 //end迭代器。返回tail,因?yàn)樗欢ㄊ莾?chǔ)存最后一個(gè)元素的結(jié)點(diǎn)的后一個(gè)。 314 315 reverse_iterator rbegin( ) 316 { 317 return reverse_iterator( tail->prev ); 318 } 319 const_reverse_iterator rbegin( ) const 320 { 321 return const_reverse_iterator( tail->prev ); 322 } 323 //逆向begin迭代器,返回tail的前一個(gè)迭代器。 324 325 reverse_iterator rend( ) 326 { 327 return reverse_iterator( head ); 328 } 329 const_reverse_iterator rend( ) const 330 { 331 return const_reverse_iterator( head ); 332 } 333 //逆向end迭代器,返回head節(jié)點(diǎn)的迭代器。 334 335 int size( ) 336 { 337 return theSize; 338 } //返回鏈表的大小。 339 bool empty( ) 340 { 341 return size( ) == 0; 342 } 343 344 void clear( ) 345 { 346 while( !empty( ) ) 347 pop_front( ); 348 } 349 //將鏈表清空。 350 Object & front( ) 351 { 352 return *begin( ); 353 } 354 const Object & front( ) const 355 { 356 return *begin( ); 357 } 358 //返回第一個(gè)元素,即返回begin迭代器指向的元素。調(diào)用iterator的(*)操作符。 359 Object & back( ) 360 { 361 return *--end( ); 362 } 363 const Object & back( ) const 364 { 365 return *--end( ); 366 } 367 //返回最后一個(gè)元素,即返回end迭代器的前一個(gè)結(jié)點(diǎn)的元素。 368 void push_front( const Object & x) 369 { 370 insert( begin( ), x ); 371 } 372 //頭插入!調(diào)用insert函數(shù),在第一個(gè)元素前插入新的元素。 373 void push_back( const Object & x ) 374 { 375 insert( end( ), x ); 376 } 377 //尾插入!調(diào)用insert函數(shù),在表尾結(jié)點(diǎn)前插入新的元素,相當(dāng)于插在最后一個(gè)元素的后面。 378 void pop_front( ) 379 { 380 erase( begin( ) ); 381 } 382 //刪除第一個(gè)元素,調(diào)用erase函數(shù)。 383 void pop_back( ) 384 { 385 erase( --end( ) ); 386 } 387 //刪除最后一個(gè)函數(shù)。所以end迭代器返回的迭代器要自減才是最后一個(gè)函數(shù)。 388 iterator insert( iterator itr, const Object & x ) 389 { 390 Node *p = itr.current; 391 theSize++; 392 return iterator( p->prev = p->prev->next = new Node( x, p->prev, p ) ); 393 } 394 //將新的結(jié)點(diǎn)插入指定的迭代器的前面。見圖二。 395 iterator erase ( iterator itr) 396 { 397 Node *p = itr.current; 398 iterator retVal( p->next ); 399 p->prev->next = p->next; 400 p->next->prev = p->prev; 401 delete p; 402 theSize--; 403 404 return retVal; 405 } //刪除迭代器指向的結(jié)點(diǎn),并返回一個(gè)迭代器,指向被刪除元素后面的元素。 406 iterator erase ( iterator start, iterator end ) 407 { 408 for( iterator itr = start; itr != end; ) 409 itr = erase( itr ); 410 411 return end; 412 } 413 414 //刪除迭代器start和end所標(biāo)記的范圍所有元素,返回一個(gè)迭代器,指向被刪除元素段后面的元素。 415 416 void splice( iterator position, List<Object> & lst ) 417 { 418 Node *p = position.current; 419 420 p->prev->next = lst.head->next; 421 lst.head->next->prev = p->prev; 422 lst.tail->prev->next = p; 423 p->prev = lst.tail->prev; 424 425 theSize += lst.size(); 426 427 lst.init(); 428 } 429 430 friend iterator find(iterator start, iterator end, const Object & x ) 431 { 432 iterator itr = start; 433 while( itr != end && *itr != x ) 434 { 435 ++itr; 436 } 437 return itr; 438 } 439 440 private: 441 int theSize; //鏈表的大小 442 Node *head; //表頭結(jié)點(diǎn) 443 Node *tail; //表尾結(jié)點(diǎn) 444 445 void init() 446 { 447 theSize = 0; 448 head = new Node; 449 tail = new Node; 450 head->next = tail; 451 tail->prev = head; 452 } //init函數(shù),初始化鏈表。見圖一 453 }; 454 455 456 int main( ) 457 { 458 List<int> l1; 459 List<int> l2; 460 int num, m; 461 cout << "l1的元素?cái)?shù)量:" << endl; 462 cout << l1.size() << endl; 463 if( l2.empty() ) 464 cout << "l2為空的!" << endl; 465 else 466 cout << "l2不是空的!" << endl; 467 cout << "輸入你想插入鏈表的元素個(gè)數(shù):" << endl; 468 cin >> num; 469 for(int i = 1; i <= num; ++i) 470 { 471 cin >> m; 472 l1.push_back(m); 473 l2.push_front(m); 474 } 475 476 /*List<int>::iterator itr1 = l1.begin(); 477 List<int>::iterator itr = itr1 + 5; 478 cout << *itr << endl;*/ 479 //3.14 480 481 /*List<int>::iterator itr1 = l1.begin(); 482 List<int>::iterator itr2 = --l2.end(); 483 List<int>::iterator itr = find( itr1, itr2, 20); 484 cout << *itr << endl;*/ 485 //3.3 486 487 /*List<int>::reverse_iterator itr1 = l1.rbegin(); 488 while( itr1 != l1.rend() ) 489 cout << *itr1++ <<" "; 490 cout << endl;*/ 491 //3.16 492 493 /*List<int>::iterator pos = l1.begin(); 494 l1.splice( pos, l2 ); 495 496 for(List<int>::iterator itr = l1.begin(); itr != l1.end(); ++itr) 497 cout << *itr << " "; 498 cout << endl;*/ 499 //3.15 500 501 cout << "l1的元素?cái)?shù)量:" << endl; 502 cout << l1.size() << endl; 503 cout << "l2的元素?cái)?shù)量:" << endl; 504 cout << l2.size() << endl; 505 cout << "l1是尾插入,l2是頭插入!!!!" << endl; 506 cout << "l1的全部元素順序輸出:" << endl; 507 for(List<int>::iterator itr = l1.begin(); itr != l1.end(); ++itr) 508 cout << *itr << " "; 509 cout << endl; 510 cout << "l2的全部元素順序輸出:" << endl; 511 for(List<int>::iterator itr = l2.begin(); itr != l2.end(); ++itr) 512 cout << *itr << " "; 513 cout << endl; 514 cout << "l1的第一個(gè)元素: " <<l1.front() << endl; 515 cout << "l1的最后一個(gè)元素: " <<l1.back() << endl; 516 cout << "l2的第一個(gè)元素: " <<l2.front() << endl; 517 cout << "l2的最后一個(gè)元素: " <<l2.back() << endl; 518 List<int> l3(l1); 519 cout << "l3為調(diào)用復(fù)制構(gòu)造函數(shù)!" << endl; 520 cout << "l3中元素的數(shù)目:" << endl; 521 cout << l3.size() << endl; 522 cout << "輸出l3的全部元素!(與l1的全部元素比較,同一個(gè)位置上的元素是一樣!)" << endl; 523 for(List<int>::iterator itr = l3.begin(); itr != l3.end(); ++itr) 524 cout << *itr << " "; 525 cout << endl; 526 List<int>::iterator itr1 = l3.begin(); 527 l3.erase( itr1 ); 528 cout << "對(duì)l3調(diào)用erase函數(shù),刪除begin迭代器所知指向的元素!" << endl; 529 cout << "輸出l3中元素的數(shù)數(shù)目:" << endl; 530 cout << l3.size() << endl; 531 cout << "輸出l3的全部元素:" << endl; 532 for(List<int>::iterator itr = l3.begin(); itr != l3.end(); ++itr) 533 cout << *itr << " "; 534 cout << endl; 535 List<int>::iterator itr2 = l3.begin(); 536 List<int>::iterator itr3 = l3.end(); 537 l3.erase( itr2, itr3); 538 cout << "對(duì)l3調(diào)用erase函數(shù),刪除迭代器begin和end之間的全部元素!" << endl; 539 cout << "輸出l3重元素的數(shù)目!" << endl; 540 cout << l3.size() << endl; 541 return 0; 542 }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/alan-forever/archive/2012/09/12/2682437.html
總結(jié)
以上是生活随笔為你收集整理的STL之list学习(2)(list代码实现)(只剩最后一步,迭代器升级!!)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 初学者学MvcMovie遇到的问题解决办
- 下一篇: httpModule过滤无后缀名的文件夹