STL容器解讀筆記

2021-10-04 22:28:37 字數 2525 閱讀 6142

15.allocator函式呼叫malloc函式時,malloc函式除了會分配size大小的空間外,還會附加上一些資訊,組合成一整塊的記憶體。但是揮著就會造成乙個問題,分配size的實際大小會比其他的附加資訊還要小,這實際上就會造成記憶體的浪費,實際分配的要比size大很多。因此,gnuc2.9上面實現c++的記憶體分配alloc時使用了特殊的機制去防止這種記憶體的浪費。因為malloc每次呼叫都會帶著overhead的額外開銷,所以gnuc2.9上面的對策是儘量減少呼叫malloc的次數。內部建立了16條鍊錶,每一條鍊錶負責一種size型別的分配,#0代表8個位元組的記憶體分配,第n條鍊錶負責8n+8個位元組的記憶體分配。容器需要記憶體的話都會調這個鍊錶獲取記憶體,如果申請的記憶體不是8的倍數,那麼需要先調整到8的倍數再進行分配。但是,現在使用的gnc4.9還是直接呼叫malloc函式。

16.deque深度探索

deque是一種看似連續實際是分段儲存的資料型別。實現原理:內部有許多長度相同的快取buffer,每個buffer都有乙個指標指向它,然後這些指向buffer的指標有序的放在乙個vector中,每當需要擴充size,向前或者向後申請一段新的buffer。原始碼上儲存指標的容器就是乙個vector,deque的迭代器是由乙個類組成的,裡面有四個元素,都是指標型別佔16個位元組的空間,cur,first,last,node。node指的是每個buffer的指標,first和last是node指出的buffer的頭和尾,cur指的是當前指向的元素。過載++,–,+=,-=等符號型別時,由於本身deque是分段的因此需要判斷是否到了所在buffer的邊界,如果到了邊界需要先退回node所在的vector,計算出操作之後正確的緩衝區,然後再跳到那個buffer上移動到正確的位置。+=就是-=的反向操作。i=i+5,i=i-5=i±5。

deque儲存指標的vector在元素放滿之後會自動擴充,尋找一塊兩倍於現在的記憶體,再將現在的元素全部複製過去,但是複製到新的記憶體中是複製到中段,這樣前後擴充元素就比較方便。

17.容器queue 先進先出

內含乙個deque,然後封住一些功能,就得到queue的屬性。

18.容器stack 先進後出

內含乙個deque,然後封住一些功能,就得到stack的屬性。

stack和queue不允許遍歷和迭代器。

19.紅黑樹

一種平衡二元搜尋樹。這種樹的特徵:排列規則有利於search和insert,並保持適度平衡,不會出現特別長的節點。

中序遍歷是可以將元素從小到大遍歷輸出。

rb_tree提供兩種insertion操作:insertion_unique()和insertion_equal()。前者表示只能插入不重複的元素,後者表示可以插入重複的元素。

rb_tree為map和set兩種容器提供底部支援。map的key不可重複只有data可以重複。

在stl中rb_tree的定義如下:

_rb_tree, key_compare, _alloc>

gnu2.9->gnu4.9 主體的實現不變,但是為了遵循handle and body的規則,將主要的實現部分寫在另乙個類中,然後用乙個base類使用組合的方式,用指標使用主體內的實現。

20.容器set,由於set內部實現都是呼叫底層的紅黑樹進行操作,因此本質上set並不是乙個容器,而是乙個content adapter,只是呼叫底層真正儲存資料的rb_tree的介面。

21.vc6.0和gnu2.9對於identity的實現是類似的,vc6.0是set實現了乙個內部的struct,而gnu2.9使用的是外部的struct。

22.map/multimap具有自動排序性,因為底層的結構都是rb_tree,排序的依據是key。map內部自動將key的型別加上const,因此不能隨意修改key的值。

map獨有的過載,中括號中放key,返回對應的data,並且在這個key沒有的情況下會自動建立,並且返回預設值。

lower_bound是二分查詢的一種版本,試圖在sorted list中尋找元素。如果能找到與value相等的元素,那麼返回iterator指向其第乙個key。如果沒有找到,那麼就返回乙個如果存在此元素,該元素應該存在的位置,也就是返回第乙個不大於尋找元素的位置。

hashtable 原本hashtable的設計是給定乙個比元素個數少的表,當元素的超過表的size大小時,則將元素的編號除size的餘數,得到的餘數就是元素在表中的位置,但為了元素不發生碰撞,超出部分的元素放置位置的演算法就變得比較複雜,因此就大量消耗儲存元素的時間,最後被廢棄。最終都在用seprate chaining的方式,將餘數的元素串成鍊錶來做。但是這樣也會有乙個問題,就是每乙個籃子下面的鍊錶會很長。所以,又規定,當放置的元素的總量大於籃子的size時,就需要對這個hashtable進行rehashing,使其籃子的size擴充兩倍。hashtable的size一般選質數,gnuc裡面選的是53,因此其擴充時,原本應該為106,但是最接近106的質數為97,因此選擇擴充為97。

hashtable的hashfunction使用的是偏特化的方式,將不同型別的object進行編號,返回的hashcode最好不重複,是隨機的數。

gnuc中沒有為string型別提供hashfunction,因此需要自己補充。

c++11之後,將hash開頭的容器名稱改為unordered開頭。

STL學習筆記 map multimap容器

簡介 map是標準的關聯式容器,乙個map是乙個鍵值對的序列,即 key,value 提供基於key的快速檢索能力 map中key的值是唯一的。map中的元素按照一定的順序排列,元素插入是按照排序規則插入的,不能指定位置插入 map的具體實現是紅黑樹變體的平衡二叉樹資料結構。插入和刪除比vector...

STL學習筆記 關聯容器

stl中常用的關聯容器有四種 set map mutimap multiset。這四種容器中的元素都是按照鍵有序排列的,因此關聯容器的鍵值必須是可比較的。如果鍵值是基本型別可以直接使用,如果鍵值是自定義型別,需要定義帶有比較謂詞的建構函式map中儲存著一系列的鍵值對兒,每個鍵對應乙個值,鍵類似有索引...

C 容器(STL容器)

容器 container 用於存放資料的類模板。可變長陣列 鍊錶 平衡二叉樹等資料結構在stl中都被實現為容器。在使用容器時,即將容器類模型例項化為容器類,會指明容器中存放的元素是什麼型別。容器可以分為兩大類 順序容器和關聯容器 順序容器有可變長動態陣列vector 雙端佇列deque 雙向鍊錶li...