C++之deque

 

            deque(包含頭文件#include<deque>)由若干段連續空間串接而成,一旦有必要在deque的頭部或尾端增長新的空間,便配置一段定量連續的空間,串接在deque的頭部或尾端。deque的最大任務,就是在這些分段連續的空間上維護其總體連續的假象,並提供隨機存取的接口。ios

            實際上。deque內部會維護一個map(注意!不是STL中的map容器)即一小塊連續的空間,該空間中每一個元素都是指針,指向另外一段(較大的)區域,這個區域稱爲緩衝區,緩衝區用來保存deque中的數據。所以deque在隨機訪問和遍歷數據會比vector慢。它首次插入一個元素,默認會動態分配512字節空間,當這512字節空間用完後,它會再動態分配本身另外的512字節空間,而後虛擬地連在一塊兒。deque的這種設計使得它具備比vector複雜得多的架構、算法和迭代器設計。它的隨機訪問和遍歷性能比vector差。算法

            deque是一種優化了的對序列兩端元素進行添加和刪除操做的基本序列容器。一般由一些獨立的區塊組成,第一區塊朝某方向擴展,最後一個區塊朝另外一方向擴展。它容許較爲快速地隨機訪問但它不像vector同樣把全部對象保存在一個連續的內存塊,而是多個連續的內存塊。而且在一個映射結構中保存對這些塊以及順序的跟蹤。架構

 

一.成員函數

   

構造函數與析構函數:

    

迭代器訪問操做函數

      這裏c表明常量const,r表明reverse逆操做.ide

 

值訪問操做和狀態斷定操做

         注意沒有提供容量操做capacity()。除了at(),沒有任何成員函數會檢查索引或迭代器是否有效。元素的插入或刪除可能致使內存從新分配,因此任何插入或刪除動做都會使全部指向deque元素的指針、引用和迭代器失效。唯一例外的是在頭部或尾部插入元素,操做以後,指針和引用仍然有效,但迭代器將失效。函數

 

值修改操做

         注意,pos爲迭代器類型。僅僅只有使用erase操做及刪除數據操做纔會返回指向下一個數據的迭代器。push_back()或push_front()插入元素時發生異常,不會拋出異常。另外還包括賦值函數assign(),以下:性能

 

  1. #include <iostream>  
  2. #include <deque>  
  3.   
  4. int main ()  
  5. {  
  6.   std::deque<int> first;  
  7.   std::deque<int> second;  
  8.   std::deque<int> third;  
  9.   
  10.   first.assign (7,100);             // 7 ints with a value of 100  
  11.   
  12.   std::deque<int>::iterator it;  
  13.   it=first.begin()+1;  
  14.   
  15.   second.assign (it,first.end()-1); // the 5 central values of first  
  16.   
  17.   int myints[] = {1776,7,4};  
  18.   third.assign (myints,myints+3);   // assigning from array.  
  19.   
  20.   std::cout << "Size of first: " << int (first.size()) << '\n';  
  21.   std::cout << "Size of second: " << int (second.size()) << '\n';  
  22.   std::cout << "Size of third: " << int (third.size()) << '\n';  
  23.   return 0;  
  24. }  

 

 

代碼2:常見操做優化

 

  1. #include <deque>  
  2. #include <cstdio>  
  3. #include <algorithm>  
  4. using namespace std;  
  5. int main()  
  6. {  
  7.     deque<int> ideq(20); //Create a deque ideq with 20 elements of default value 0  
  8.     deque<int>::iterator pos;  
  9.     int i;  
  10.     for (i = 0; i < 20; ++i)  
  11.         ideq[i] = i;  
  12.   
  13.     printf("輸出deque中數據:\n");  
  14.     for (i = 0; i < 20; ++i)  
  15.         printf("%d ", ideq[i]);  
  16.     putchar('\n');  
  17.   
  18.     //在頭尾加入新數據  
  19.     printf("\n在頭尾加入新數據...\n");  
  20.     ideq.push_back(100);  
  21.     ideq.push_front(i);  
  22.   
  23.     //輸出deque  
  24.     printf("\n輸出deque中數據:\n");  
  25.     for (pos = ideq.begin(); pos != ideq.end(); pos++)  
  26.         printf("%d ", *pos);  
  27.     putchar('\n');  
  28.   
  29.     //查找  
  30.     const int FINDNUMBER = 19;  
  31.     printf("\n查找%d\n", FINDNUMBER);  
  32.     pos = find(ideq.begin(), ideq.end(), FINDNUMBER);//注意迭代器類型在此查找  
  33.     if (pos != ideq.end())  
  34.         printf("find %d success\n", *pos);  
  35.     else  
  36.         printf("find failed\n");  
  37.   
  38.     //在頭尾刪除數據  
  39.     printf("\n在頭尾刪除數據...\n");  
  40.     ideq.pop_back();  
  41.     ideq.pop_front();  
  42.   
  43.     //輸出deque  
  44.     printf("\n輸出deque中數據:\n");  
  45.     for (pos = ideq.begin(); pos != ideq.end(); pos++)  
  46.         printf("%d ", *pos);  
  47.     putchar('\n');  
  48.     return 0;  
  49. }  


 

 

二.容器之間的差別和聯繫

 

           1.vector  (連續的空間存儲,可使用[]操做符)快速的訪問隨機的元素,快速的在末尾插入元素,可是在序列中間歲間的插入,刪除元素要慢(涉及元素複製移動),並且若是一開始分配的空間不夠的話,有一個從新分配更大空間,此時須要拷貝的性能開銷。能夠快速地在最後添加刪除元素,並能夠快速地訪問任意元素spa

       2.deque    在開始和最後添加刪除元素都同樣快,並提供了隨機訪問方法,像vector同樣使用[]訪問任意元素,可是隨機訪問速度比不上vector快,由於它要內部處理堆跳轉deque也有保留空間.另外,因爲deque不要求連續空間,因此能夠保存的元素比vector更大,這點也要注意一下.還有就是在前面和後面添加元素時都不須要移動其它塊的元素。對deque的排序操做,可將deque先複製到vector,排序後在複製回deque。
            1)兩端都能快速插入元素和刪除元素(vector只在尾端快速進行此類操做)。
         2)存取元素時,deque的內部結構會多一個間接過程,因此元素的存取和迭代器的動做會稍稍慢一些。
         3)迭代器須要在不一樣區塊間跳轉,因此必須是特殊的智能型指針,非通常指針。
         4)在對內存區塊有所限制的系統中(例如PC系統),deque能夠內含更多元素,由於它使用不止一塊內存。所以deque的max_size()可能更大。
         5)deque不支持對容量和內存重分配時機的控制。特別要注意的是,除了頭尾兩端,在任何地方插入或刪除元素,都將致使指向deque元素的任何指針、引用、迭代器失效。不過,deque的內存重分配優於vector,由於其內部結構顯示,deque沒必要在內存重分配時複製全部元素。
         6)deque的內存區塊再也不被使用時,會被釋放。deque的內存大小是可縮減的。

 

           3.list(元素間使用鏈表相連)訪問隨機元素不如vector快,隨機的插入元素比vector快,對每一個元素分配空間,因此不存在空間不夠,從新分配的狀況。list能夠快速地在全部地方添加刪除元素,可是隻能快速地訪問最開始與最後的元素設計

           4.set 內部元素惟一,用一棵平衡樹結構來存儲,所以遍歷的時候就排序了,查找比較快。指針

           5.map 一對一的映射的結合,key不能重複。

           6.stack 適配器,必須結合其餘的容器使用,stl中默認的內部容器是deque。先進後出,只有一個出口,不容許遍歷。

           7.queue 適配器。是受限制的deque,內部容器通常使用list較簡單。先進先出,不容許遍歷和元素的隨機訪問。

           須要說明的是:因爲deque能夠從首位兩端插入或剔除元素,因此只須要對其進行簡單的封裝就能夠分別實現先進先出(FIFO)的stack和先進後出(FILO)的queue了。stack和queue中都有一個deque類型的成員,用作數據存儲的容器,而後對deque的部分接口進行簡單的封裝,例如stack只提供從末端插入和刪除的接口以及獲取末端元素的接口,而queue則只提供從尾部插入而從頭部刪除的接口以及獲取首位元素的接口。像這樣具備「修改某物接口,造成另外一種風貌」的性質的,稱爲配接器(adapter),所以STL中stack和queue每每不被歸類爲容器(container),而被歸類爲容器配接器(container adapter)。

            

三.容器的選擇

 

          1.強調快速隨機訪問。則vector要比list好得多 。           2.已知要存儲元素的個數。vector 好於list。             3.強調增刪且不要在兩端插入修改元素。則list顯然要比vector好。             4.除非咱們須要在容器首部插入和刪除元素,deque好於vector。由於vector僅僅在尾部增刪快速。           6.若是隻須要在讀取輸入時在容器的中間位置插入元素,而後須要隨機訪問元素,則可考慮輸入時將元素讀入到一個List容器,而後排序,而後將排序後的list容器複製到一個vector容器中。           5.若是隻在容易的首部和尾部插入數據元素,則選擇deque.

相關文章
相關標籤/搜索