程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++標准庫順序容器

C++標准庫順序容器

編輯:C++入門知識

 

所有的標准庫容器都是類模板,用以存儲單一類型元素的集合。順序容器按元素位置存儲訪問,關聯容器按鍵存儲訪問。

 

 

1 順序容器

 

  將單一類型的元素按順序存儲,以下標來訪問元素。標准庫定義了三種順序容器:vector,list及deque。vector支持快速隨機訪問;list支持快速插入刪除;deque是雙端隊列。

 

  a)容器初始化:

 

  C<T> c; 創建一個名為c的容器,容器類型為C,如vector或list,T為容器內元素類型。適用於所有容器;

 

  C c1(c); 創建容器c的副本,c1和c必須具有相同的容器類型和元素類型,適用於所有容器;

 

  C c(b,e); 創建容器c,元素是迭代器b,e標示范圍內的副本,適用於所有容器;

 

  C c(n,t); 創建容器c,元素為n個值為t的值,t的類型必須是容器C的元素類型或者可以轉換為該類型,只適用於順序容器;

 

  C c(n); 創建具有n個值初始化元素的容器c,元素類型為值n的類型,只適用於順序容器;

 

  注:* 在使用迭代器復制元素時,不要求雙方容器類型相同,容器內元素類型也可以不同,只要元素類型可以相互轉換即可;

 

      * 迭代器范圍[b,e)是左閉右開區間,即e所指的元素並未被復制,e只是提供了停止復制的條件;

 

 

 

  b)元素類型約束:

 

  元素類型必須滿足:

 

  元素類型必須支持賦值;

 

  元素類型的對象必須可以復制;

 

  關聯容器的鍵類型必須且只要實現<操作符即可。

 

  注:*大多數類型都能滿足上述最低限制的約束。例外,引用不支持一般意義上的賦值,IO庫類型不支持復制或賦值,所以兩者以及auto_ptr類型都不能作為容器的元素類型。

 

 

2 迭代器

 

  一種數據類型,用於遍歷容器內元素,標准庫容器都有自己的迭代器,配合算法使用。迭代器是標准庫容器類型的配套設施。

 

  a)迭代器范圍是一個左閉右開的區間,即[b,e);

 

  b)一些容器操作會使指向容器元素的迭代器失效,要特別注意。

 

  c)const_iterator迭代器和const迭代器的區別;

 

  注:*迭代器往往和容器及泛型算法結合使用,本節僅簡單描述,後面會有詳盡的介紹。

 

 

3 順序容器的操作

 

  a)begin和end操作:

 

    c.begin(),c.end(),c.rbegin(),c.rend();

 

    非const版本:vector<string>::iterator = c.begin();

 

                 vector<string>::reverse_iterator = c.rbegin();

 

    const版本:  vector<string>::const_iterator = c.begin();

 

                 vector<string>::const_reverse_iterator = c.rbegin();

 

  b)添加操作:

 

     c.push_back();在容器尾部添加值為t的元素,返回void;

 

     c.push_front();在容器頭部添加值為t的元素,返回void,只適用於list和deque;

 

     c.insert(p,t);在迭代器p所指向的元素前面插入值為t的元素,返回指向t的迭代器;

 

     c.insert(p,n,t);在迭代器p所指向的元素前面插入n個值為t的元素,返回void;

 

     c.insert(p,b,e);在迭代器p所指向的元素前面插入由迭代器b和e標記的范圍內的元素,返回void;

 

  注:*添加元素可能會使迭代器失效,所以每次操作之後都應該及時更新迭代器;

 

  c)容器大小:

 

     c.size();返回容器內元素個數,返回類型為c::size_type;

 

     c.max_size();返回容器內最多可容納的元素個數,返回類型為c::size_type;

 

     c.empty();測試容器內是否有元素;

 

     c.resize(n);調整容器大小,使其能容納n個元素;

 

     c.resize(n,t);調整容器大小,使其能容納n個元素,新添加元素以t初始化;

 

  注:*c.resize(n)中,當n < c.size(),刪除多出來的元素;否則,采用值初始化添加新元素;

 

      *c.reserve(n);僅調整c的最大容量,並不初始化元素;

 

      *c.resize(n)和c.resize(n,t)可能會使迭代器失效;

 

  d)訪問元素:

 

     c.front();返回容器內第一個元素的引用,如果c為空,該操作未定義;

 

     c.back();返回容器內最後一個元素的引用,如果c為空,該操作未定義;

 

     c[n];和c.at(n);返回下標為n的元素的引用,n越界時,該操作未定義,只用於vector和deque;

 

  e)刪除元素:

 

     c.erase(p);刪除迭代器p指向的元素,返回一個指向被刪除元素後面的元素的迭代器;

 

     c.erase(b,e);刪除迭代器b和e標記范圍內的所有元素,返回一個指向被刪除元素段後面的元素的迭代器;

 

     c.clear();刪除容器內的所有元素,返回void;

 

     c.pop_back();刪除容器的最後一個元素,返回void;

 

     c.pop_front();刪除容器的第一個元素,返回void,只適用於list和deque;

 

  注:*刪除元素可能會使迭代器失效,所以每次操作之後都應該及時更新迭代器;

 

  f)賦值操作:

 

     cl = c2;刪除cl的所有元素,將c2的所有元素復制給c1,c1和c2的容器類型及元素類型必須相同;

 

     cl.swap(c2);交換c1和c2中的所有元素,c1和c2的容器類型及元素類型必須相同;

 

     c.assign(b,e);重新給c賦值,內容為b和e所標記范圍內的元素,b和e必須不是指向c中的元素的迭代器;

 

     c.assign(n,t);將c中的元素重新設置為n個值為t的元素;

 

  注:*賦值和assign操作會使左操作數中的迭代器失效,但是swap操作後,迭代器仍然指向相同的元素;

 

      *swap操作在常量時間內完成,沒有移動任何元素;

 

 

4 vector容器的自增長

 

  vector預留了額外的存儲區,用於存放新添加的元素,當現有的空間用完之後再自動重新分配存儲空間。capacity()和reserve()使程序員可以和vector的內存分配的實現部分交互工作。

 

  a)c.capacity();獲取c在要分配更多的存儲空間之前所能容納的元素總數;

 

  b)c.reserve(n);c應該預留n個元素的存儲空間;

 

  注:*c.resize(n);和c.reserve(n);的區別很微妙,前者對多出來的新元素進行值初始化;後者僅僅調整存儲空間,而不進行任何初始化。

 

      *c.max_size();和c.capacity();的區別也很微妙。簡單的說,c.max_size();是c.capacity();的最大值,前者是一個常量,值取決於操作系統或C++庫的實現,而後者則是一個變量。 

 

 

     www.cplusplus.com/reference/stl/vector/max_size/有清晰的描述。

 

      *c.size(); <= c.capacity(); <= c.max_size();

 

 

5 順序容器的選用

 

  a)順序容器的特點:

 

  vector容器可以實現高效的隨機訪問,但是除了容器尾部外,在其他任何位置添加和刪除元素卻很低效;

 

  list容器可以實現高效的添加刪除,但是隨機訪問的效率卻很低;

 

  deque容器支持對所有元素的隨機訪問,在容器的首部和尾部可以高效地添加刪除元素,但是在中間位置添加刪除元素卻又很低效。

 

  注:*應用中占優勢的操作將決定使用哪種類型的容器。

 

 

6 容器適配器

 

  適配器概念的定義:是一種標准庫類型,函數或迭代器,使一種標准庫類型,函數或迭代器的行為類似於另一種標准庫類型,函數或迭代器。本質上,適配器是使一種事物的行為類似於另

 

 

一種事物行為的機制。容器適配器在其基礎容器上定義一個新的接口,使基礎容器擁有另一種不同容器的工作方式。

 

  順序容器適配器:stack(棧),queue(隊列),priority_queue(優先級隊列)。

 

  a)容器適配器通用的操作和類型:

 

     size_type 一種類型,存儲此適配器類型最大對象的長度;

 

     value_type 元素類型;

 

     container_type 基礎容器的類型;

 

     A a;創建一個新的容器適配器;

 

     A a(c);創建一個新的容器適配器a,初始化為c的副本;

 

     關系操作符:==,!=,<,<=,>,>=。

 

  b)適配器的初始化:

 

     deque<int> deq;

 

     stack<int> stk();

 

     stack<int> stk(deq);

 

  注:*stack適配器和queue適配器的基礎容器默認為deque,priority_queue的基礎容器默認為vector。

 

  c)覆蓋基礎容器類型:

 

     deque<int> deq;

 

     stack<int,vector<int> > stk(deq);

 

  注:*stack適配器關聯的基礎容器可以是任意一種順序容器類型;

 

      *queue適配器要求基礎容器必須提供push_frong操作,只能建立在list容器上;

 

      *priority_queue適配器要求提供隨機訪問操作,只能建立在vector或deque容器上;

 

  d)棧適配器的操作:

 

     s.empty();返回棧是否為空;

 

     s.size();返回棧中的元素個數;

 

     s.pop();刪除棧頂元素,返回void;

 

     s.top();返回棧頂元素,但不刪除該元素;

 

     s.push(item);在棧頂壓入新元素;

 

  注:*程序員不能直接使用棧適配器所關聯的基礎容器的操作。

 

  e)隊列和優先級隊列的操作:

 

     q.empty();返回隊列是否為空;

 

     q.size();返回隊列中的元素個數;

 

     q.pop();刪除隊首元素,返回void;

 

     q.front();返回隊首元素,但不刪除元素,只適用於隊列;

 

     q.back();返回隊尾元素,但不刪除元素,只適用於隊列;

 

     q.top();返回具有最高優先級的元素,但不刪除該元素,只適用於優先級隊列;

 

     q.push(item);對於queue,在隊尾壓入一個元素;對於priority_queue,在基於優先級的適當位置插入一個元素。

作者:馬哈魚

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved