STL 中各容器的比較

2021-06-20 19:19:14 字數 2869 閱讀 3382

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++在2023年之後就沒再有重大改變,並且決定不再向c++標準庫中做任何重大的變更,正是這個原因,hash   table(包括hash_map)並沒有被列入標準之中,雖然它理應在c++標準之中占有一席之地。 

雖然,現在的大多數編譯平台支援hash   table,但從可移植性方面考慮,還是不用hash   table的好。

hehe俺也來湊湊熱鬧。 

1.有的時候vector可以替代map 

比如key是整數,就可以以key的跨度作為長度來定義vector。 

資料規模很大的時候,差異是驚人的。當然,空間浪費往往也驚人。 

2.hash是很難的東西 

沒有高效低碰撞的演算法,hash_***沒有意義。 

而對不同的型別,資料集,不可能有優良的神仙演算法。必須因場合而宜。 

俺有的解決方法是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各容器的實現原理

stl共有六大元件 容器 演算法 迭代器 仿函式 介面卡 空間配置器 stl的實現是基於我們常見的資料結構 vector 動態陣列 list 雙鏈表 deque 分配 控制器map,map記錄著一系列的固定長度的陣列的位址。deque先從map 的位置 因為雙向佇列,前後都可以插入元素 找到乙個陣列...

STL中幾種常用容器比較

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

STL容器效率比較

1 vector 變長一維陣列,連續存放的記憶體塊,有保留記憶體,堆中分配記憶體 支援操作,高效率的隨機訪問 在最後增加元素時,一般不需要分配記憶體空間,速度快 在中間或開始操作元素時要進行記憶體拷貝效率低 vector高效的原因在於配置了比其所容納的元素更多的記憶體,記憶體重新配置會花很多時間 注...