1. 程式人生 > >STL 容器區別:vector、list、deque、set、map的底層實現

STL 容器區別:vector、list、deque、set、map的底層實現

1、set和map

比較

\ set map
共同點 都是無序的儲存元素,只是通過它提供的藉口對裡面的元素進行訪問,底層都是採用紅黑樹實現
不同點 集合,用來判斷某一個元素是不是在一個組裡面,使用的比較少 對映,相當於字典,把一個值對映成另一個值,可以建立字典

總結:

a. 優點

  • 查詢某一個數的時間為O(logn)
  • 遍歷時採用iterator,效果不錯

b. 缺點

  • 每次插入值的時候,都需要調整紅黑樹,效率有一定影響

2、vector

概述

是動態陣列,在堆中分配記憶體,元素連續存放,有保留記憶體,如果減少大小後,記憶體也不會釋放;如果新值大於當前大小時才會重新分配記憶體。

特點

  • 擁有一段連續的記憶體空間,並且起始地址不變,因此能夠非常好的支援隨機存取,即[]操作符,但是由於它的記憶體空間是連續的,所以在頭部和中間進行插入和刪除操作會造成記憶體塊的拷貝,另外,當該陣列的記憶體空間不夠時,需要重新申請一塊足夠大得記憶體並且進行記憶體的拷貝,這些都大大的影響了vector的效率。
  • 對頭部和中間進行新增刪除元素操作需要移動記憶體,如果你得元素是結構或類,那麼移動的同時還會進行構造和析構操作,所以效能不高
  • 對任何元素的訪問時間都是O(1),所以常用來儲存需要經常進行隨機訪問的內容,並且不需要經常對中間元素進行新增刪除操作
  • 屬性與string差不多,同樣可以使用capacity看當前保留的記憶體,使用swap來減少它使用的記憶體,如push_back 1000個元素,capacity返回值為16384
  • 對最後元素操作最快(在後面新增刪除元素最快),此時一般不需要移動記憶體,只有保留記憶體不夠時才需要

總結

  • 需要經常隨機訪問且不用經常對中間元素刪除插入時使用vector
  • 如果元素是結構或類,最好是將結構或類的指標放入vector中,這樣不僅能夠節省空間,而且可以避免移動時構造和析構操作
  • 刪除元素時採用後面的元素覆蓋前面的元素的方法可以提高效率

    3、list

    概述

    雙向連結串列,元素也存放在堆中,每個元素都是放在一塊記憶體中,他的記憶體空間可以是不連續的,通過指標來進行資料的訪問,這個特點使得它的隨機存取變得非常沒有效率,因此它沒有提供[]操作符的過載。但是由於連結串列的特點,它可以很有效率的支援任意地方的刪除和插入操作。

    特點

  • 沒有空間預留習慣,所以沒分配一個元素都會從記憶體中分配,沒刪除一個元素都會釋放它佔用的記憶體
  • 在哪裡新增刪除元素效能都很高,不需要移動記憶體,當然也不需要對每個元素都進行構造與析構了,所以常用來做隨機插入和刪除操作容器
  • 訪問開始和最後兩個元素最快,其他元素的訪問時間都是O(n)

    總結

  • 如果經常進行新增和刪除操作並且不經常隨機訪問的話,使用list
  • list<指標>完全是效能最低的做法,還不如直接使用list<物件>或使用vector<指標>好,因為指標沒有構造與析構,也不佔用很大記憶體

    4、deque

    概述

    【堆1】

    【堆2】

    【堆3】

    特點

  • 支援[]操作符,也就是支援隨機存取,有比較搞的隨機存取速度,由於deque需要處理內部跳轉,因此速度上沒有vector快
\ deque vector
組織方式 按頁或塊來分配儲存器的,每頁包含固定數目的元素 分配一段連續的記憶體來儲存內容
效率 即使在容器的前端也可以提供常數時間的insert和erase操作,而且在體積增長方面也比vector更具有效率 只是在序列的尾端插入元素時才有效率,但是隨機訪問速度要比deque快
  • 支援兩端操作push_back、push_front、pop_back、pop_front等,並且效率與list差不多

    總結

  • 如果既需要隨機存取,又需要兩端資料插入和刪除,則應該使用deque

    5、總結

\ vector ist deque
特點 快速的隨機存取,快速的在最後插入刪除元素 可以快速的在任意位置新增刪除元素,只能快速的訪問最開始和最後面的元素 在開始和最後新增刪除元素一樣快,並且提供了隨機訪問的方法
適用 需要高效的隨機存取,不在於插入刪除的效率 需要大量的插入和刪除操作,不關心隨機存取 需要隨機存取,也需要高效的在兩端進行插入刪除操作