1. 程式人生 > >STL 容器簡介

STL 容器簡介

轉自:https://www.cnblogs.com/wxquare/p/7119724.html

STL(標準模板庫)庫是用模板(template)寫出來的,模板是STL的基礎。STL分為:容器,迭代器,介面卡,演算法,函式物件。其中容器分為:順序性容器,關聯式容器。迭代器有5種:隨機訪問迭代器,雙向迭代器,前向迭代器,輸入迭代器,輸出迭代器。 

一、概述

STL 對定義的通用容器分三類:順序性容器、關聯式容器和容器介面卡。

順序性容器是一種各元素之間有順序關係的線性表。元素在順序容器中儲存元素置入容器時的邏輯順序,除非用刪除或插入的操作改變這個位置,否則元素的位置保持為原來的位置。

關聯式容器是非線性的結構,包含二叉樹結構和hash結構。元素在關聯容器中沒有儲存元素置入容器時的邏輯順序。但是關聯式容器提供了另一種根據元素特點排序的功能,這樣迭代器就能根據元素的特點“順序地”獲取元素。關聯容器另一個顯著的特點是它是以鍵值的方式來儲存資料,就是說它能把關鍵字和值關聯起來儲存,而順序性容器只能儲存一種。

容器介面卡。介面卡是使一事物的行為類似於另一事物的行為的一種機制。容器介面卡以某種容器作為底部結構,將其介面改變,使得它滿足與另一種資料結構的介面,例如藉助deque分別實現stack和queue介面,藉助vector實現priority_queue介面。

二、順序容器

1 .vector動態陣列<連續儲存、隨機訪問、檢索快、只能在後端新增刪除>

vector是一個線性順序結構。相當於動態陣列,其大小可以預先指定也可以不指定,並且自動擴充套件,它可以像陣列一樣被操作。在建立一個vector 後,它會自動在記憶體中分配一塊連續的記憶體空間進行資料儲存,初始的空間大小可以預先指定也可以由vector 預設指定,這個大小即capacity ()函式的返回值。當儲存的資料超過分配的空間時vector 會重新分配一塊記憶體塊,但這樣的分配是很耗時的,在重新分配空間時它會做重新分配空間、拷貝與釋放原有空間三個動作。如果vector 儲存的資料量很大時,這樣的操作一定會導致糟糕的效能(這也是vector 被設計成比較容易拷貝的值型別的原因)。所以說vector 不是在什麼情況下效能都好,只有在預先知道它大小的情況下vector 的效能才是最優的。

2.雙向迴圈連結串列list<不連續儲存、不支援隨機訪問、支援任意位置插入刪除>

list是一個線性連結串列結構,它的資料由若干個節點構成,每一個節點都包括一個實際儲存的資料、一個前驅指標和一個後驅指標。它無需分配指定的記憶體大小且可以任意伸縮,這是因為它儲存在非連續的記憶體空間中,並且由指標將有序的元素連結起來。由於其結構的原因,list 隨機檢索的效能非常的不好,因為它不像vector 那樣直接找到元素的地址,而是要從頭一個一個的順序查詢,這樣目標元素越靠後,它的檢索時間就越長。檢索時間與目標元素的位置成正比。雖然隨機檢索的速度不夠快,但是它可以迅速地在任何節點進行插入和刪除操作。因為list 的每個節點儲存著它在連結串列中的位置,插入或刪除一個元素僅對最多三個元素有所影響,不像vector 會對操作點之後的所有元素的儲存地址都有所影響,這一點是vector不可比擬的。

3.雙向佇列deque<vector和list特點結合,支援隨機訪問、支援內部插入刪除>

deque是一種優化的、對序列兩端元素進行新增和刪除操作的基本序列容器。它允許較為快速地隨機訪問,但它不像vector 把所有的物件儲存在一塊連續的記憶體塊,而是採用多個連續的儲存塊,並且在一個對映結構中儲存對這些塊及其順序的跟蹤。向deque 兩端新增或刪除元素的開銷很小。它不需要重新分配空間,所以向末端增加元素比vector 更有效。實際上,deque 是對vector 和list 優缺點的結合,它是處於兩者之間的一種容器。deque有如下幾個特點:

vector、list和deque 的比較:vector 是一段連續的記憶體塊,而deque 是多個連續的記憶體塊,list 是所有資料元素分開儲存。vector 的查詢效能最好,並且在末端增加資料也很好,除非它重新申請記憶體段;適合高效地隨機儲存。list是一個連結串列,任何一個元素都可以是不連續的;deque是介於兩者之間,它兼顧了陣列和連結串列的優點。

三、關聯容器

set, multiset, map, multimap 是一種非線性的樹結構,具體的說採用的是一種比較高效的特殊的平衡檢索二叉樹—— 紅黑樹結構。因為關聯容器的這四種容器類都使用同一原理,所以他們核心的演算法是一致的,但是它們在應用上又有一些差別,先描述一下它們之間的差別。

1.set ,又稱集合,實際上就是一組元素的集合,但其中所包含的元素的值是唯一的,且是按一定順序排列的,集合中的每個元素被稱作集合中的例項。因為其內部是通過連結串列的方式來組織,所以在插入的時候比vector快,但在查詢和末尾新增上被vector 慢。

2.multiset ,是多重集合,其實現方式和set 是相似的,只是它不要求集合中的元素是唯一的,也就是說集合中的同一個元素可以出現多次。

3.map ,提供一種“鍵- 值”關係的一對一的資料儲存能力。其“鍵”在容器中不可重複,且按一定順序排列(其實我們可以將set 也看成是一種鍵-值關係的儲存,只是它只有鍵沒有值。它是map 的一種特殊形式)。由於其是按連結串列的方式儲存,它也繼承了連結串列的優缺點。

4.multimap和map的原理基本相似,它允許“鍵”在容器中可以不唯一。

5.unordered_map和map類似,都是儲存的key-value的值,可以通過key快速索引到value。不同的是unordered_map不會根據key的大小進行排序,儲存時是根據key的hash值判斷元素是否相同,即unordered_map內部元素是無序的,而map中的元素是按照二叉搜尋樹儲存,進行中序遍歷會得到有序遍歷。所以在使用map的key時,需要定義operator<,而在使用unordered_map需要定義雜湊函式,並且過載operator==

6.unordered_set類似

四、容器介面卡

STL 中包含三種介面卡:棧stack 、佇列queue 和優先順序priority_queue。

1.stack 是一種先進後出(First In Last Out , FILO)的資料結構。它只有一個出口,stack 允許新增元素,移除元素,取得最頂端元素。但除了最頂端外,沒有任何其它方法可以存取stack的其它元素,stack不允許遍歷行為。以某種容器作為底部結構,將其介面改變,使之符合“先進後出”的特性,形成一個stack,是很容易做到的。deque是雙向開口的資料結構,若以 deque為底部結構並封閉其頭端開口,便輕而易舉地形成了一個stack.因此,SGI STL 便以deque作為預設情況下的stack底部結構,由於stack 系以底部容器完成其所有工作,而具有這種"修改某物介面,形成另一種風貌"之性質者,稱為adapter(配接器),

2.queue是一種先進先出(First In First Out,FIFO) 的資料結構。它有兩個出口,queue允許新增元素,移除元素,從最底端加入元素,取得最頂端元素。但除了最底端可以加入,最頂端可以取出外,沒有任何其它方法可以存取queue的其它元素。以某種容器作為底部結構,將其介面改變,使之符合“先進先出”的特性,形成一個queue,是很容易做到的。deque是雙向開口的資料結構,若以 deque為底部結構並封閉其底部的出口和前端的入口,便輕而易舉地形成了一個queue.

3.heap和priority:heap 並不歸屬於STL容器元件,是priority queue的助手。priority queue允許使用者以任何次序將任何元素推入容器中,但取出時一定按從優先權最高的元素開始取。按照元素的排列方式,heap可分為max-heap和 min-heap兩種,前者每個節點的鍵值(key)都大於或等於其子節點鍵值,後者的每個節點鍵值(key)都小於或等於其子節點鍵值。因此, max-heap的最大值在根節點,並總是位於底層array或vector的起頭處;min-heap的最小值在根節點,亦總是位於底層array或 vector起頭處。