STL 原始碼閱讀

2021-08-05 22:54:07 字數 3229 閱讀 1150

1、這裡可以看出來,容器將迭代器作為類成員。

vectora;

iteratorite=a.begin();

容器的成員函式可以返回迭代器,所以迭代器是容器的成員物件。

2、個人理解,迭代器是對指標的封裝和提公升,盡可能遮蔽資料結構的底層細節,對外提供統一的操作介面,這些介面跟普通指標的功能類似,比如自增或自減,提取所指向的元素等。

為什麼不直接用指標?

指標在可以隨機訪問的資料結構(陣列)上有較好和簡潔的表現,但是對不能隨機訪問的資料結構,一些操作是不簡潔的(如鍊表的下一節點,就不能簡單自增和自減,而是將指標封裝,對運算子進行過載,在過載的運算函式內,實現繁瑣的步驟)

3、deque

有點像vector

和list

的結合體,繼承了兩種結構的優勢。會動態增加和刪除緩衝區,但是不會改變未受影響的緩衝區,所以不會像

vector

那樣容易指標失效。

4、deque

迭代器指向的元素是緩衝區,內容包括

cur、

first

、last

、node

5、為什麼不用

vector

實現stack

記憶體和效率的原因吧,

vector

最大的優勢在於快速的隨機訪問,但是其插入即慢又浪費空間(

vector

插入會導致重新分配記憶體並拷貝物件,所以慢;而且其預留很大的備用空間所以,會浪費空間。對棧這種經常變動大小,而又最後歸於空的結構不適合)。

deque

雖然在隨機訪問方面會比

vector

差些,但是動態地在尾部插入、刪除的效率平均要比

vector

高,其差的方面隨機訪問

stack

又不需要,所以選擇

deque

最為底層實現結構。

6、list

也可以實現

stack

,但是stl

預設用deque

實現。

7、stack

和queue

都用deque

和list

實現,而非

vector

實現,是他們都不需要隨機訪問(都沒有迭代器,不能訪問中間元素)。若用到隨機訪問,比如最優佇列需要用到堆排序,

heap

不是stl

元件,那麼

vector

是更好的選擇。

8、二叉樹的深度和高度都是通過路徑長度來衡量的,深度是根節點到指定節點的路徑長度(因此,深度和路徑長度總是相等的,高度是指定節點到其最深葉子節點的路徑長度)

二叉樹根節點是第一層,往下以此類推,二叉樹深度就是層數。

9、底層採用

rb-tree

實現的關聯式容器,儲存結構為鍊錶、會自動排序,所以一定注意這一點。而且,針對鍵值是否可以重複的不同實現,也是依賴

rb-tree

的兩個不同

insert

函式實現的:

insert_unique()

(set

、map

的實現依賴)和

insert_equal()

(multiset

、multimap

的實現依賴)。值得注意的是,向

map或

set插入重複鍵值,並不會報錯,只是沒有效果,但是可以根據返回值進行判斷。

10、stl hashtable

底層用鏈位址法作為解決

hash

衝突的方法,用

vector

作為**,每個元素對應

list

的頭指標(

list

有尾節點,預設的插入是尾插,所以準確講是尾節點的指標)。

hashtable

的存在就是為了快速的搜尋查詢,因為使用了鍊錶,那麼對鍊錶的訪問必定是線性複雜度,但是只要

list

鍊錶夠短,那麼速度就夠快,影響就是可以接受的。

11、為什麼

hashtable

的vector

大小(也叫桶大小)選取質數?

是為了減少雜湊衝突。

桶大小的選取是如何影響雜湊衝突的呢?下面有兩種看法:

a

、舉個例子,對於除法雜湊表(

division method

)h(k)=k mod m

注意二進位制數對取餘就是該二進位制數最後

r位數。這樣一來,

hash

函式就和鍵值(用二進位制表示)的前幾位數無關了,這樣我們就沒有完全用到鍵值的資訊,這種選擇

m的方法是不好的。所以好的方法就是用質數來表示

m,使得這些質數,不太接近

2的冪或者

10的冪。

b

、首先來說假如關鍵字是隨機分布的,那麼無所謂一定要模質數。但在實際中往往關鍵字有某種規律,例如大量的等差數列,那麼公差和模數不互質的時候發生碰撞的概率會變大,而用質數就可以很大程度上迴避這個問題。

12、list

是雙向鍊錶,它用的節點是尾節點,而非常見頭結點(便於操作的統一),

begin()

返回的是

node

結點的下一節點,

node

位於尾部,因為

list

首尾相連,所以就是指向

list

的頭部。

end()

返回的就是

node

節點,記住

end()

返回的迭代器是無效的。

insert()

插入資料到指定迭代器的前面。

STL原始碼閱讀 二

vector的記憶體分配基類 template class vector alloc base vector alloc base的偏特化版本,不需要儲存記憶體分配器 template class vector alloc base tp,allocator,true template struct...

STL原始碼閱讀 七

set使用紅黑樹實現,每個鍵值都不相同,且按序儲存。注意operator 即 rb tree的實現 先銷毀賦值號左邊的set,然後將右邊的set拷貝給左邊的set,而不是原值替換。set的所有函式都是用 rb tree的函式實現的,相當於 rb tree的乙個包裝類。multiset使用紅黑樹實現,...

STL原始碼閱讀 八

字串的雜湊函式 f s 5 f s 1 s,當len s 1,則f s s 其中s是指向字串的指標。示例 inline size t stl hash string const char s template struct hash sgi hash table碰撞檢測方法是鏈結法,雜湊表的每個槽都...