條目四《用empty來代替檢查size()是否為0》
阿新 • • 發佈:2018-12-21
條目四《用empty來代替檢查size()是否為0》
首先先說結論:
- empty()實現為行內函數。(眾所周知, 優秀的行內函數的效率比一般函式是高的)
- 在stl標準庫中,empty()對所有容易的時間複雜度是常數時間, 而對於一些list實現,size()是線性時間的。
基於以上兩點, 在實際使用中, 需要判斷容易的元素是否為0時,最好的選擇是使用empty()函式。
造成size()在list容器的特殊性是由於list中splice()的存在。
在實現list時,有兩點是需要注意的:
- 1.為了高效,讓list知道自己的size是多大,即把size()做成時間複雜度是常數級別(每向list插入元素就往size()返回的變數自增1)
- 2.選用list, 就是因為list的特殊性,兩個list拼接的時間複雜度只是常數級別的。所以把splice()做成時間複雜度是常數級別。
以上兩點可以並存嗎?
很抱歉,不能並存。
為了讓** size()常數級別 ,就是在呼叫splice()後呼叫size()的時間複雜度是常數級別,必須在splice後馬上 遍歷 **被splice的list的元素更新新list的size,這樣後面再使用size()就是常數時間,因為list已經知道自己的size了。
但是這樣做,區間splice()就不是常數時間了,而是線性時間。
為了讓** splice()常數級別 ,那麼在splice時就應該忽略size的更新,拋棄更新被拼接list的size()成員函式。等到在呼叫size()的時候再
但是這樣做, size()就不是常數時間了,而是線性時間。
究其原因是區間splice()在底層實現不是一個一個插入元素的,而是根據迭代器的始末,來一次拷貝元素達到目的,所以才有條目五。
所以在list中,size()和區間splice()不能同時是常數時間,在實際實現時要看我們比較傾向哪一個,如果基本不適用區間splice,那麼可以把size實現為是常數時間的。
這一切,關鍵看需求......