STL中的deque學習筆記

2021-08-04 23:26:26 字數 3237 閱讀 3964

deque可以理解為乙個雙端佇列,它是一種雙向開口的連續性空間(可在頭尾兩端分別做元素的插入和刪除操作)。

來看下它的空間結構組織:

從圖中我們可以看到deque的記憶體不是整體連續的,而是由一段一段的定量連續空間構成。它給我們的假象是整體連續,並提供了隨機訪問的介面。所以為了維持這種整體連續的假象,它的資料結構的設計以及迭代器的前進後退等操作都頗為繁瑣。(實現**可想而知比其他兩個順序性容器多得多)

來看看它的資料結構設計:

template

class

deque

分析deque的迭代器應該具備的結構

templatet,class ref,class ptr,size_t bufsiz>

struct _deque_iterator

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

從上面deque的資料結構分析,除了上面說的map二級指標外,它也維護start,finish兩個迭代器。這兩個迭代器分別指向第一緩衝區的第乙個元素和最後緩衝區的最後元素(的下一位置)。當然也得記錄中控器的大小(map_size),因為一旦map所提供的節點不足,就必須重新配置更大的一塊map。

在迭代器中有個重要的函式是set_node(),是跳到下乙個緩衝區

來看下加入first、finish迭代器的後deque的記憶體管理方式圖

deque的基本函式使用如下:

#include

using

namespace

std;

#include

#include

#include

void main()

cout

<< "deq.size()= "

<< deq.size() << endl; //列印其大小

deq.push_front(100); //從deque最前面加入乙個元素

//訪問deque中的元素

cout

<< "deq.at(0) = "

<< deq.at(0) << endl;

cout

<< "deq[3] = "

<< deq[3] << endl;

deque

::iterator it = deq.begin();

for (; it != deq.end(); it++)

cout

<< endl;

//deque的元素操作

deq.insert(deq.begin() + 4, 900); //在位置i前面插入某一元素

cout

<< deq.at(4) << endl;

deq.insert(deq.begin(),ideq.begin(), ideq.end()); //插入一整段元素

cout

<< deq.size() << endl;

deq.pop_back(); //刪除尾元素

deq.pop_front(); //刪除首元素

deq.erase(deq.begin()); //清除首元素

deq.erase(deq.begin(), deq.begin() + 2); //清除[first,last)區間內的所有元素

cout

<< deq.size() << endl;

deq.clear(); //清除所有元素

cout

<< deq.size() << endl;

}

來分析下細節問題:

插入元素:

如果在頭部插入乙個元素,則會先比較start迭代器的內容,即start.cur 和start.first是否相等,相等說明第一緩衝區沒有備用空間,所以會呼叫push_front_axu()函式申請一塊緩衝區,在中控器中對應的指標會指向它,當然也會改變start迭代器node項的指向。假設插入的是99,即ideq.push_front(99);

在尾部插入和首部插入類似,如果最後一塊緩衝區有備用空間則,只改變finish迭代器的cur指標,否則重新申請一塊緩衝區作為最後一塊緩衝區。

在中間的插入需要注意的是在插入乙個元素(或一區間元素)後,insert()函式內部會先檢查插入的元素位置之前的元素多還是插入元素位置之後的元素多,取元素少的方向進行元素的移動。

刪除元素:

刪除元素和插入元素類似,在次不再贅述。值得注意的是清除中間位置的元素時,erase()函式內部也會先判斷清除位置之前的元素和清除位置之後的元素的大小。會取元素少的方向進行元素的移動。

deque迭代器失效的問題

#include

using

namespace

std;

#include

#include

void main()

測試內容與c++primer(第五版上的描述相吻合),即

解釋如下~~~~~~~~

插入操作:

1、在隊頭或隊尾插入元素時(push_back(),push_front()),可能緩衝區的空間不夠,需要增加map中控器,而中控器的個數也不夠,所以新開闢更大的空間來容納中控器,所以可能會使迭代器失效;但指標、引用仍有效,因為緩衝區已有的元素沒有重新分配記憶體。

2、在佇列其他位置插入元素時,由於會造成緩衝區的一些元素的移動(原始碼中執行copy()來移動資料),所以肯定會造成迭代器的失效;並且指標、引用都會失效。

刪除操作:

1、刪除隊頭或隊尾的元素時,由於只是對當前的元素進行操作,所以其他元素的迭代器不會受到影響,所以一定不會失效,而且指標和引用也都不會失效;

2、刪除其他位置的元素時,也會造成元素的移動,可能會涉及到中控器的改變,所以其他元素的迭代器、指標和引用都會失效。

STL學習筆記之 (三)容器 deque

deque,即double end queue,雙向佇列。不同的平台會提供不同版本的deque實現策略,但歸結起來,deque應該是一種指標陣列實現。使用deque可以實現元素的隨機訪問和遍歷,同時在起始端和末端插入和刪除元素的效率很高 但是,在中間部分插入和刪除元素會導致很低的工作效率。deque...

STL學習筆記 序列式容器deque

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

STL學習(三)deque容器學習

deque的操作函式 建構函式和析構函式 非變動性操作 變動性操作 deque記憶體 deque從邏輯上來看是連續的記憶體,本質上是由一段段固定大小 的連續空間組成。deque採用類似索引的結構管理記憶體,如下 採用一小塊連續的記憶體索引快取結點,每乙個快取結點也是一段連續的空間,可以儲存多個資料。...