1. 程式人生 > >STL中幾種常用容器比較

STL中幾種常用容器比較

list支援快速的插入和刪除,但是查詢費時;

vector支援快速的查詢,但是插入費時。

map查詢的時間複雜度是對數的,這幾乎是最快的,hash也是對數的。 
如果我自己寫,我也會用二叉檢索樹,它在大部分情況下可以保證對數複雜度,最壞情況是常數複雜度,而std::map在任何情況下都可以保證對數複雜度,原因是它保證存諸結構是完全二叉檢索樹,但這會在存諸上犧牲一些時間。

STL   中的   map   內部是平衡二叉樹,所以平衡二叉樹的性質都具備。查詢資料的時間也是對數時間。 vector,在分配記憶體上一般要比   new   高效的多。

為什麼說   hash_map   是對數級的?在不碰撞的情況下,hash_map是所有資料結構中查詢最快的,它是常數級的。 
如果對問題設計了足夠好的hash

演算法,保證碰撞率很低,hash_map的查詢效率無可置疑。 
另外,STL的map,它的查詢是對數級的,是除hash_map外最高的了,你可以說“也許還有改進餘地”,但對於99.9999%的程式設計師,設計一個比STL   map好的map,我執悲觀態度。 
STL的map有平衡策略(比如紅黑樹什麼的),所以不會退化,不需要考慮資料本身的分佈問題。只不過,如果資料本身是排好序的,用vector或heap會明顯的快些,因為它們的訪問比較簡單。

我想沒必要懷疑stl::map的查詢效率,影響效率最主要的因素是什麼?演算法,在查詢問題上,有什麼演算法比RB_tree更好嗎?至少現在還沒有。不否 認你可以通過自己寫程式碼,設計一個符合你需要的BR—TREE,比stl::map簡捷那麼一點,但最多也就每次迭代中少一行指令而已,處理十萬個數據多 執行十萬行指令,這對你重要嗎?如果你不是在設計

OS像LINUX,沒人會關注這十萬行指令花的時間。 
rb-tree的時間花在了插入和刪除上,如果你不是對插入和刪除效率要求很高,你沒有理由不選擇基於rb-tree的stl::map。

大多數程式設計師寫不出比std::map更好的map,這是當然的。然而並不是std::map的所有特性都出現在我們的程式中,自己編寫的可以更適合自己的程式,的確會比std::map更快一些。

關於hash_map,它與map的實現機制是不一樣的,map內部一般用樹來實現,其查詢操作是O(logN)的,這個沒有爭議,我就不多說了。 
hash_map的查詢,內部是通過一個從key到value的運算函式來實現的,這個函式“只接受key作為引數”,也就是說,hash_map的查詢 演算法與資料量無關,所以認為它是O(1)級的。來這裡的應該都是達人,可以參看《資料結構》。當然,事實總不這樣完美,再引一段前面我自已說的話,進一步 說明,以免誤會:

----------------------------------------- 
在不碰撞的情況下,hash_map是所有資料結構中查詢最快的,它是常數級的。 
------------------------------------------ 
注意我的前提:“在不碰撞的情況下”,其實換句話說,就是要有足夠好的hash函式,它要能使key到value的對映足夠均勻,否則,在最壞的情況下,它的計算量就退化到O(N)級,變成和連結串列一樣。 
如果說   hash_map   是所有容器中最慢的,也只能說:“最拙劣的hash函式”會使hash_map成為查詢最慢的容器。但這樣說意義不大,因為,最湊巧的排列能使氣泡排序成為最快的排序演算法。

BS: "對於大型容器而言,hash_map能夠提供比map快5至10倍的元素查詢速度是很常見的,尤其是在查詢速度特別重要的地方.另一方面,如果hash_map選擇了病態的雜湊函式,他也可能比map慢得多. "

ANSIC++在1998年之後就沒再有重大改變,並且決定不再向C++標準庫中做任何重大的變更,正是這個原因,hash   table(包括hash_map)並沒有被列入標準之中,雖然它理應在C++標準之中佔有一席之地。 
雖然,現在的大多數編譯平臺支援hash   table,但從可移植性方面考慮,還是不用hash   table的好。

hehe俺也來湊湊熱鬧。 
1.有的時候vector可以替代map 
比如key是整數,就可以以key的跨度作為長度來定義vector。 
資料規模很大的時候,差異是驚人的。當然,空間浪費往往也驚人。 
2.hash是很難的東西 
沒有高效低碰撞的演算法,hash_xxx沒有意義。 
而對不同的型別,資料集,不可能有優良的神仙演算法。必須因場合而宜。 
俺有的解決方法是GP,可不是飯型,是遺傳程式設計,收效不錯。

你的百萬級的資料放到vector不大合適。因為vector需要連續的記憶體空間,顯然在初始化這個容器的時候會花費很大的容量。 
使用map,你想好了要為其建立一個主鍵嗎?如果沒有這樣的需求,為什麼不考慮deque或者list? 
map預設使用的是deque作為容器。其實map不是容器,拿它與容器比較意義不大。因為你可以配置它的底層容器型別。

如果記憶體不是考慮的問題。用vector比map好。map每插入一個數據,都要排序一次。所以速度反不及先安插所有元素,再進行排序。

用 binary_search對已序區間搜尋,如果是隨機存取iterator,則是對數複雜度。可見,在不考慮記憶體問題的情況下,vector比map 好。

如果你需要在資料中間進行插入,list 是最好的選擇,vector   的插入效率會讓你痛苦得想死。

涉及到查詢的話用map比較好,因為map的內部資料結構用rb-tree實現,而用vector你只能用線性查詢,效率很低。

stl還提供了 hash容器,理論上查詢是飛快~~~。做有序插入的話vector是噩夢,map則保證肯定是按key排序的,list要自己做些事情。

HASH型別的查詢肯定快,是對映關係嘛,但是插入和刪除卻慢,要做移動操作, LIST型別的使鏈式關係,插入非常快,但是查詢卻費時,需要遍歷~~ , 還是用LIST型別的吧,雖然查詢慢點,

先快速排序,然後二分查詢,效率也不低

相關推薦

STL常用容器比較

list支援快速的插入和刪除,但是查詢費時; vector支援快速的查詢,但是插入費時。 map查詢的時間複雜度是對數的,這幾乎是最快的,hash也是對數的。  如果我自己寫,我也會用二叉檢索樹,它在大部分情況下可以保證對數複雜度,最壞情況是常數複雜度,而std::m

C++STL常用容器簡要歸納

本文參考李煜東《演算法競賽進階指南》,筆者作歸納總結。 本文將簡要介紹STL中vector,queue,priority_queue,deque,set,multiset,map,bitset八種容器及其操作方法。 vector 使用此容器需在程式前加上標頭檔

java 常用數據結構

初學 ble log app 使用 blog list 好的 sort Java中有幾種常用的數據結構,主要分為Collection和map兩個主要接口(接口只提供方法,並不提供實現),而程序中最終使用的數據結構是繼承自這些接口的數據結構類。 一、幾個常用類的區別 1.

C#常用的集合的用法

col div tex -c 組成 相同 列表 對象 count 集合:將一推數據類型相同的數據放入到一個容器內,該容器就是數組:內存中開辟的一連串空間。 非泛型集合 ArrayList集合: ArrayList是基於數組實現的,是一個動態數組,其容量能自動 增

JAVA常用的RPC框架介紹

github 不同的 target int https love num 分布 有一個 RPC是遠程過程調用的簡稱,廣泛應用在大規模分布式應用中,作用是有助於系統的垂直拆分,使系統更易拓展。Java中的RPC框架比較多,各有特色,廣泛使用的有RMI、Hessian、Du

Java 常用的線程池

需要 表示 ali adf data future rate 並發 ng- Java 中幾種常用的線程池 轉載 : https://www.cnblogs.com/sachen/p/7401959.html 原創 2016年04月14日 23:29:01 標簽: j

selenium常用的等待

提起selenium中的等待,最先浮入你腦海的會是什麼呢? time sleep? 顯式等待? 隱式等待? …………   1.time sleep() 可以稱其為暫停等待,當設定為time.sleep(3)時意味著程式在等待3s後才會執行下一步查詢下一位元素,比較適合沒

網際網路常用的傳輸協議

網際網路中幾種常用的網路傳輸協議 網路傳輸協議多種多樣,各有所長,學起來真的很讓人頭大。 對協議的學習需要不斷地使用不斷加深理解。本篇就是我的個人學習筆記。 --一個正在努力學習的碼農新人 協議那麼多,常用的也就那麼幾個 程序/應用程協議 常見協議有:Telnet、FT

java開發過程常用演算法

排序演算法 排序演算法中包括:簡單排序、高階排序   簡單排序  簡單排序常用的有:氣泡排序、選擇排序、插入排序 氣泡排序程式碼如下: 1 private static void bubbleSrot(int[] arr) { 2 3 for (int

java開發過程常用算法

font sea 順序 包括 基數 本機 ade 算法 運行時間 排序算法 排序算法中包括:簡單排序、高級排序 簡單排序 簡單排序常用的有:冒泡排序、選擇排序、插入排序 冒泡排序代碼如下: 1 private static void bubbleSrot(in

ASP.NET MVC常用ActionResult

一、定義 MVC中ActionResult是Action的返回結果。ActionResult 有多個派生類,每個子類功能均不同,並不是所有的子類都需要返回檢視View,有些直接返回流,有些返回字串等。ActionResult是一個抽象類,它定義了唯一的ExecuteResult方法,引數為一個C

MVC常用ActionResult

一、定義 MVC中ActionResult是Action的返回結果。ActionResult 有多個派生類,每個子類功能均不同,並不是所有的子類都需要返回檢視View,有些直接返回流,有些返回字串等。ActionResult是一個抽象類,它定義了唯一的ExecuteResul

DNS服務常用服務的配置方法

DNS域名解析服務 域名作為替代IP地址的訪問名稱,構成是由頂級域名—代表國家,機構或組織等,二級域名—企業名稱或品牌名稱等,主機名—www或主機所提供的服務名稱等自主命名組成,相較於IP地址,域名更容易被理解和記憶。 鑑於網際網路中的域名和 IP 地址對應關係資料庫太

java常用的資料結構

JAVA中有幾種常用的資料結構,主要分為Collection和map兩個主要介面(介面值提供方法,並不提供實現),而程式中最終使用的資料結構是繼承自這些介面的資料結構類。 Collcation: Map: 一、幾個常用類的區別  1.ArrayList: 元素單個,

聚類分析演算法的比較

將資料庫中的物件進行聚類是聚類分析的基本操作,其準則是使屬於同一類的個體間距離儘可能小,而不同類個體間距離儘可能大,為了找到效率高、通用性強的聚 類方法人們從不同角度提出了近百種聚類方法,典型的有K-means方法、K-medoids方法、CLARANS方法,BIRCH方

Android常用的定時器和延時方法

通過實際專案的練習,掌握了幾種android基本定時器和延時的用法,這裡我想總結一下作為自己的收穫,下面列出的是比較簡潔的模式,方便簡單地在程式中直接呼叫。 一、三種常用的定時器 1.Handler類的postDelayed方法: H

MFC常用的字串分割方法

功能介紹:從iStart位置取出字串中含pszTokens分割符間的內容;istart是開始分割的位置,一般設為0,下面是一段運用例項: 1 2 3 4 5 6 7 8 9 10 11 12

Matplotlib常用的圖形(四)

條形圖 條形圖常常用來描述一組資料的對比情況,例如:一週七天,每天的城市車流量等。【條形圖有兩個引數x,y】bar()繪製豎直條形圖、barh()繪製水平條形圖。 匯入繪圖工具包: import matplotlib.pyplot as plt imp

Java常用的分頁

... List<StudentEnroll> students = studentlDao.getAllStudents(); int count = 0; if(studentEnrolls != null && studentEnrolls.s

angularjs2 常用的型別(String,Number)等

let a:Number=1;//數值型別 let b:String = 'angularjs2';//字元型別 let c:boolean = true; //布林型別 let d:Number [