1. 程式人生 > >隨心所語之容器(C++ Container)

隨心所語之容器(C++ Container)

    作為軟體開發者,必然會用到各種各樣的容器:vector(array),list,map,set,tree等等(主要針對C++)。那麼,其中的區別是什麼麼?官方教程(資料結構教科書)有些簡單的對比、對其特徵有描述。但是,真正用的時候,卻仍然覺得飄忽,或者說憑感覺用,沒有道理可言。

    今天,突然來了點靈感,這裡講講我的感受。

    容器,顧名思義,就是用來放東西的。那麼,這些東西都是有一定的特徵的。根據這些不同的特徵,會選擇不同的容器。

1、順序性(注意,這裡的順序,指的是放進容器的先後順序,而非資料大小順序)

    這種特徵的資料,很明顯用順序性的資料結構,vector(array),list等(stack是先進先出,vector,list都能達到效果。所以,vector/list完全夠用, 這裡就不單獨列出stack)。

    那麼,這種順序性容器,如何區分使用呢?list對比vector最大的優勢就是插入、刪除特別方便。所以,一般都用list。當然,如果資料個數相對比較固定,而且主要是在尾部操作,或者全量操作,那麼,用vector也是不錯的。

舉例:socket通訊,獲取N個訊息指標,丟佇列放其他執行緒處理。

     1)list的情況:如果其他多個執行緒執行緒,一次就從佇列取一個訊息,那麼(頭刪除,尾插入,插入刪除特別頻繁)。

     2)vector情況:如果,其他執行緒就一個,將訊息全部取出快取(vector可以swap),再一個個處理。處理結束後再全部清除(vector可以用clear)。

     附註:當然,情況2用list也能達到相同的效果。但是,這種特徵下,vector比list快,而且遍歷方便。

2、查詢型資料結構,儲存key/value型資料物件

     許多資料需要提供查詢,一般都有一個key。這種資料,就需要用到查詢型資料結構了。

     查詢型資料結構,一般主要有tree、hash表。

1)hash表沒啥好說的,就是通過雜湊函式進行對映,所以速度相對很快(比較好的情況,複雜度為O(1))。C++中有unordered_map/unordered_set等。

2)tree有查詢樹,AVL-Tree,RB-Tree,B-Tree,B+Tree。RB-Tree就是C++中的map實現。B樹(B/B+)主要用於索引建立(資料庫,磁碟讀寫用的比較多)。(C++中,b樹沒有具體的實現容器,需要自己實現)。

     查詢樹可以提高查詢速度,但是,可能會不平衡;所以就產生了AVL-Tree。AVL-Tree操作很複雜,於是有了相對要求不是很嚴格的RB-Tree(map)。

     B/B+是多叉樹(平衡的)。這樣就降低了高低,降低了查詢次數。所以,一般用來做索引。

舉例:一般用到的就是map和hash表。如果僅僅是查詢,對key沒有順序要求,那麼就用hash表好了。如果對key的順序性要求,那麼用map。

3)skiplist。是list的擴充套件。我自己也不知道使用場景,沒做過對比。使用場景,就見過redis中有。

網上介紹跳錶,說到的存在價值,一般都會說,rb-tree太複雜。skiplist實現簡單。所以,我想它的存在意義就是自己實現簡單,所以,更多是存在於C語言中(C++中有map,skiplist也許並不存在特別優勢)

特別說明:heap是一種排序演算法,不是資料結構(一般用陣列或者樹來實現)。一般用於top10等應用。

3、無特徵資料物件。

     這種資料物件沒有任何要求,各個物件沒有任何差別,完全相同的意義:沒有順序,沒有key。這種資料一般用list來存放(一般要經常性取出/放入)。不用查詢型資料結構是因為沒有key。

舉例:一般的資源型物件就沒有差別。比如說,記憶體池的一個個記憶體塊物件(相同大小是記憶體塊是沒有區別的)。所以,一般用list來存放。