1. 程式人生 > >條目四《用empty來代替檢查size()是否為0》

條目四《用empty來代替檢查size()是否為0》

條目四《用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()的時候再

遍歷 **list來獲得list的size。

但是這樣做, size()就不是常數時間了,而是線性時間。

究其原因是區間splice()在底層實現不是一個一個插入元素的,而是根據迭代器的始末,來一次拷貝元素達到目的,所以才有條目五

所以在list中,size()和區間splice()不能同時是常數時間,在實際實現時要看我們比較傾向哪一個,如果基本不適用區間splice,那麼可以把size實現為是常數時間的。

這一切,關鍵看需求......