STL序列式容器之deque

2021-09-25 10:29:47 字數 3136 閱讀 2847

deque概述

vector是單向開口的連續線性空間,deque則是一種雙向開口的連續線性空間。所謂雙向開口,意思是可以在頭尾兩端分別做元素的插入和刪除操作。vector當然也可以在頭尾兩端分別做元素的插入刪除操作(從技術上說),但是其頭部操作效率極差而無法被接受。

deque和vector的最大差異,一是在於deque允許於常數時間內對起頭端進元素的插入或移除操作,二在於deque沒有所謂容量(capacity)觀念,因為它是動態地以分段連續空間組合而成,隨時可以增加一段新的空間並連線起來。換言之,如vector那樣「因舊空間不足而重新配置一塊更大空間,然後複製元素,再釋放舊空間」這樣的事情在deque是不會發生的。也因此,deque沒有必要提供所謂的空間保留(reserve)功能。

雖然deque也提供ramdon access iterator,但它的迭代器並不是普通指標,其複雜度和vector不可以道理計,因此也影響了各個運算層面。因此,除非必要,我們盡可能選擇使用vector而非deque。對deque進行的排序操作,為了最高效率,可將deque先完整複製到乙個vector身上,將vector排序後,在複製回deque。

deque的中控器

deque是連續的空間(至少邏輯上看),連續的線性空間總令我們聯想到array或vector。array無法成長,vector雖可成長,卻只能向尾部成長,而且所謂成長原是個假象,事實上a.另尋更大的空間,b.將原資料複製過去,c.釋放原空間三部曲。如果不是vector每次配置空間時都有留下一些餘裕,其成長假象帶來的代價是非常高昂的。

deque是由一段一段的定量連續空間構成。一旦有必要在deque的前端或尾端增加新空間,便配置一端定量連續空間,串接在整個deque的頭端或尾端,deque的最大任務,便是在這些分段的定量連續空間上,維護其整體連續的假象。並提供隨機訪問的介面。避開了「重新配置、複製、釋放」的輪迴,代價是複雜的迭代器架構。

受到分段連續線性空間的字面影響,我們可能以為deque的實現複雜度和vector相比雖不中也不遠,其實不然。因為分段連續線性空間必須要有**控制,而為了維持整體連續的假象,資料結構的設計及迭代器前進後退等操作都較為複雜和繁瑣。deque的實現**分量遠比vector或list都多得多。

deque採用一塊所謂的map(這裡並不是map容器)作為主控,是一小塊連續空間,其中每個元素(此處稱為乙個節點,node)都是指標,指向另一段較大的連續線性空間,稱為緩衝區。緩衝區才是deque的儲存空間主體。sgi stl允許指定緩衝區的大小,預設值為0,表示將使用512 bytes 緩衝區。

deque部分源**

map和node-buffer(節點和緩衝區)的關係

deque的迭代器

deque是分段連續空間,維持其:「整體連續」假象的任務,落在迭代器傳遞operator++和operator–兩個運運算元身上。

deque迭代器必須能夠指出分段連續空間(緩衝區)在**,其次它必須判斷自己是否已經處於其所在緩衝區的邊緣,如果是,一旦前進或者後退時就必須跳躍至下乙個或上乙個緩衝區,為了能夠正確跳躍,deque必須隨時掌握管控中心(map)。

templatestruct _deque_iterator

//未繼承 std::iterator, 所以必須自行撰寫五個必要的迭代器相應型別

typedef random_access_iterator_tag iterator_category;//(1)

typedef t value_typel;//(2)

typedef ptr pointer;//(3)

typedef ref reference;//(4)

typedef size_t size_type;

typedef ptrdiff_t difference_type;//(5)

typedef t** map_pointer;

typedef _deque_iterator self;

//保持與容器的聯接

t* cur;//此迭代器所指之緩衝區的現行元素

t* first;//此迭代器所指之緩衝區的頭

t* last;//此迭代器所指之緩衝區的尾(包含備用空間)

map_pointer node;//指向管控中心

......

}

其中用來決定緩衝區的大小的函式buff_size(),呼叫_deque_buf_size(),後者是乙個全域性函式,定義如下:

//如果n不為0,傳回n,表示buffer size有使用者自定義

//如果n為0,表示buffer size使用預設值,那麼如果sz(元素大小,sizeof(value_type))小於512,傳回512/sz;如果sz不小於512,傳回1

deque的中控器、緩衝區、迭代器的相互關係

deque的構造圖

deque的元素操作

STL序列式容器之deque

deque是一種雙向開口的連續線性空間,所謂雙向是指可以在首尾兩端進行插入和刪除,邏輯結構如圖所示 deque和vector最大的差異在於deque可以在常數時間內對頭端進行插入和刪除操作,而且deque沒有容量的概念,隨時可以增加一段新的空間並鏈結起來。除非必要,應盡量使用vector而非dequ...

stl之序列容器 deque

相比於vector,deque是一種雙向開口的連續線性空間,可以在頭尾兩端分別做元素的插入和刪除操作。這也決定了其更賦值的容器結構。deque內部維護了start和finish 節點,用於雙端的插入和刪除 map,一塊連續空間,其每個元素都是個指標,指向乙個節點。其指向的節點中有四個元素 cur f...

STL學習筆記 序列式容器deque

上一次說了list,現在再看一下序列式容器的另外幾種,常用的stack,queue,還有乙個deque,這個我不常用,所以先看一下deque的用法 1.deque vector是單向開口的連續線性空間,list是不連續的空間,支援兩邊操作,deque是一種雙向開口的連續線性空間,支援兩邊操作。由於d...