C++之deque


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

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

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


一.成員函數

   

構造函數與析構函數


    

迭代器訪問操作函數


      這里c代表常量const,r代表reverse逆操作.


值訪問操作和狀態判定操作


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


值修改操作


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

#include <iostream>
#include <deque>

int main ()
{
  std::deque<int> first;
  std::deque<int> second;
  std::deque<int> third;

  first.assign (7,100);             // 7 ints with a value of 100

  std::deque<int>::iterator it;
  it=first.begin()+1;

  second.assign (it,first.end()-1); // the 5 central values of first

  int myints[] = {1776,7,4};
  third.assign (myints,myints+3);   // assigning from array.

  std::cout << "Size of first: " << int (first.size()) << '\n';
  std::cout << "Size of second: " << int (second.size()) << '\n';
  std::cout << "Size of third: " << int (third.size()) << '\n';
  return 0;
}

代碼2:常見操作

#include <deque>
#include <cstdio>
#include <algorithm>
using namespace std;
int main()
{
	deque<int> ideq(20); //Create a deque ideq with 20 elements of default value 0
	deque<int>::iterator pos;
	int i;
	for (i = 0; i < 20; ++i)
		ideq[i] = i;

	printf("輸出deque中數據:\n");
	for (i = 0; i < 20; ++i)
		printf("%d ", ideq[i]);
	putchar('\n');

	//在頭尾加入新數據
	printf("\n在頭尾加入新數據...\n");
	ideq.push_back(100);
	ideq.push_front(i);

	//輸出deque
	printf("\n輸出deque中數據:\n");
	for (pos = ideq.begin(); pos != ideq.end(); pos++)
		printf("%d ", *pos);
	putchar('\n');

	//查找
	const int FINDNUMBER = 19;
	printf("\n查找%d\n", FINDNUMBER);
	pos = find(ideq.begin(), ideq.end(), FINDNUMBER);//注意迭代器類型在此查找
	if (pos != ideq.end())
		printf("find %d success\n", *pos);
	else
		printf("find failed\n");

	//在頭尾刪除數據
	printf("\n在頭尾刪除數據...\n");
	ideq.pop_back();
	ideq.pop_front();

	//輸出deque
	printf("\n輸出deque中數據:\n");
	for (pos = ideq.begin(); pos != ideq.end(); pos++)
		printf("%d ", *pos);
	putchar('\n');
	return 0;
}


二.容器之間的差異和聯系

           1.vector  (連續的空間存儲,可以使用[]操作符)快速的訪問隨機的元素,快速的在末尾插入元素,但是在序列中間歲間的插入,刪除元素要慢(涉及元素復制移動),而且如果一開始分配的空間不夠的話,有一個重新分配更大空間,此時需要拷貝的性能開銷。可以快速地在最后添加刪除元素,並可以快速地訪問任意元素

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


 





 

參考

      1.vector,map,list,queue的區別詳細解析

      2.STL系列之一 deque雙向隊列

      3.deque用法 和與vector的區別






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM