C STL 序列式容器與配接器的簡單使用

2022-10-03 15:39:16 字數 2920 閱讀 6771

目錄

c++標準裡提供了以下容器或容器配接器:

序列式容器

配接器關聯式容器

不定序關聯容器

array

stack

setunordered_set

vector

queue

mapunordered_map

list

priority_queue

multiset

unordered_multiset

deque

multimap

unordered_multimap

forward_list

array是靜態連續空間,一經配置,大小不可改變。

就是陣列,除了空間的靈活性不足,其他與vector很像。用的也比較少,一般都用vector了,這裡就不多說了。

vector的資料安排與操作方式,與array很相似。二者唯一的差別在於空間的運用的靈活性。

vector維護的是連續線性空間,其指標就是普通指標。

vector::iterator iter;

那麼iter其實就是int*型別。

兩個迭代器saqbnxsfbtart和finish之間是連續空間中目前已被使用的空間,end_of_storage指向整塊連續空間的尾端。

為了降低頻繁空間配置帶來的成本開銷,vector實際配置的大小會比客戶需求的更大一些,以備將來可能的擴充。這便是capacity的概念。

www.cppcns.com

一旦size() == capacity(),便是滿載。下次再有新增元素,整個vector就要另覓他所了。「另覓他所」的過程會經歷「重新配置大空間,元素移動,釋放原空間」這一系列動作,工程浩大。

所謂動態增加大小,並不是在原空間之後接續新空間(因為無法保證原空間之後有可供配置的空間),而是以原空間大小的兩倍另外配置一塊較大空間,然後將原內容拷貝過來,然後才開始在原內容後邊構造新元素,並釋放原空間。

因此,對vector的任何操作,一旦引起空間重新配置,指向原vector的所有迭代器就都失效了,這是乙個經常犯的錯誤,務必小心。

list是環狀雙向鍊錶。它的好處在於每次插入或刪除乙個元素,就配置或釋放乙個元素空間,與vector相比,list對空間運用更加精準,絕不浪費。且對於任何位置的元素插入或移除,list永遠是常數時間。

vector和list適用場景與以下有關:

list的節點結構如下:

template

struct __list_node;

由於list的記憶體空間無法保證是連續的,所以它的迭代器不再是普通指標。list的迭代器必須有能力指向list節點,並進行正確的遞增、遞減、取值、成員訪問等操作。

list的操作大多不會使迭代器失效,即便是刪除操作,也只有指向被刪除元素的那個迭代器失效。

由於list是乙個環狀雙向鍊錶,所以它只需要乙個指標,程式設計客棧便可以完整遍歷整個鍊錶。

對於insert操作,新節點將位於哨兵迭代器(標示出插入點)所指節點的前方,這是stl對插入操作的標準規範。

vector是單向開口的連續線性空間,deque則是一種雙向開口的線性連續空間。所謂雙向開口,即可以在首尾兩端分別做元素的插入和刪除操作。

deque其實是動態地以分段連續空間組合而成。但是這些分段的連續空間,在使用者看來確實一整塊連續空間,這其實是deque做出的假象。這種假象由deque的中控器map(注意,不是stl中的map容器)負責維持。

這個map可以理解為對映,它是乙個指標,指向一小段連續記憶體空間,這塊空間中的每個元素又都是乙個指標,每個指標都指向deque的分段連續空間中的某一段。預設每一段是512位元組。

forward_list是單向鍊錶。

前邊說了,對於insert操作,新節點將位於哨兵迭代器(標示出插入點)所指節點的前方,這是stl對插入操作的標準規範。

但是forward_list作為單向鍊錶,它沒有什麼方便方法回頭定出前乙個位置,它只能從頭找起,所以除了forward_list起點處附近的區域外,在其他位置insert()或erase()就很慢,對此,forward_list特別提供了insert_after()和erase_after()。

同樣出於效率考慮,它不提供push_back(),只提供push_front()。

stack是先進後出(filo)的資料結構。他只有乙個出口,除了最頂端元素外,沒有其他方法獲得stack的其他元素。即stack是不允許有遍歷行為的,自然也就沒有迭代器了。

stl中的stack其實不算是container,而是adapter,因為其底層預設是deque,把deque的頭端封閉,便形成乙個stack。

具有「修改某物介面,形成另一種風貌」之性質者,謂之adapter。

除了deque,list也是雙向開口的,所以list也可以做stack的底層結構。

queue是先進先出(fifo)的資料結構。它有兩個出入口,但都是被限制的,尾端只進不出,頭端只出不進。除了尾端進,頭端出之外,沒有其他方法訪問queue的其他元素,即queue也是不允許遍歷的,自然也就沒有迭代器了。

queue也是一種adapter,它同stack一樣,預設以deque作為底層結構,list同樣也可以做其底層結構。

把deque的頭端入口和尾端出口,就成了乙個queue。

priority_queue是擁有權值觀念的queue。

所謂擁有權值觀念,可以理解為有序的,其內的元素並非按照加入的次序排列,而是按照元素的權值排列,權值最高者排在最前邊。

預設狀態下,priority_queue是用乙個大根堆(max-heap)來完成,而大根堆是乙個以vector表現得完全二叉樹。

大根堆:max-heap,父節點值大於或等於子節點值的完全二叉樹;

小根堆:min-heap,父節點值小於或等於子節點值的完全二叉樹。

所以,priority_queue是以vector為底層結構,輔以heap處理規則來實現的,所以它也是一種adapter。

priority_queue也不允許遍歷,自然也沒有迭代器。

容器配接器 stacks

stack 堆疊 的簡單使用 include include using namespace std int main if st st1 cout st.size endl 棧中元素的個數 cout st.top endl 返回棧頂元素 st.pop 出棧 st.top 12 改變棧頂元素值 st...

STL 容器配接器

以底部容器完成所有工作,而具有這種修改某物介面而成為另一種風貌的性質者稱為配接器,因此stl stack queue priority queue都稱為容器配接器。stack是一種先進後出的資料結構,不允許有遍歷行為。stl是以deque作為預設情況下的stack底部結構。deque為底部結構並封閉...

C STL容器總結 序列式

vector容器 vector容器是最簡單的序列式容器,支援隨機訪問,隨機儲存。類似動態陣列,將元素置於動態陣列 vector可以實現佇列,陣列,堆疊的全部的功能 vector定義 vector vec vector函式 size 統計容器元素數量 capacity 返回容器最大可容納的元素數量 r...