一,hash_set
原理:說到哈希,那么必須講一下哈希表和哈希函數,這個相對於紅黑樹,又在一個角度,簡化了搜索的復雜性,以及在構造時候的繁瑣性;
哈希表:通過哈希函數,生成的一維數組,長度有限,
哈希函數,將具體的數據值,轉換為對應哈希表的索引下標的函數,舉一個例子,f(x)=x%7; 那么當你的數據值x為22的時候,算出來f(22)=1,那么這個22就存放在下標為1的位置,很簡單!
給出一個數組,比如說10個數,a1[10]={1,2,...},我們都知道,除以7,余數為1的數,太多了,那么對應相同下標的數,如何存放呢?那么就是通過鏈表,把這些書都串起來,(在更高級的java中,為了提高效率,使用的是紅黑樹,相當於:vector<set<T>>)
由此圖,舉個例子看看,給出一個哈希表的長度為7,下標為0,1,。。。6;哈希函數為f(x)=x%7那么存入的數據里面,23,16,9算出來,自然都是2,全部串起來。
我們可以發現,這個數組的效率,搞不搞,完全取決於我們的哈希表的長度取的是否恰當,如果太短,那么聊表就會累積的很長,如果取的太長,又會造成很大的空間浪費,所以,這也是哈希表的缺點不足之一,為了盡量避免,哈希表的長度,一般取為質數
功能:
增加:insert(value),這里不能指定插入的位置,因為位置是根據哈希函數指定的;
刪除:erase(),直接刪除某個元素值,或者刪除某個指針范圍;
修改:因為位置不固定,所以修改比較麻煩,等效於刪除該節點后,再插入一個新的結點
查找:find()使用哈希函數查找
遍歷:使用迭代器iterator(),從begin(),到end()遍歷;
優缺點:
優點:提高了查詢的速度,構造比較簡單,可以動態的刪除,結點與結點之間,沒有關系,不像set與map,刪除一個結點,會影響整個結構,但是如果把紅黑樹與哈希表結合后,那么該優點就會消失。
缺點:無法動態修改(修改后,會影響該點所在的位置),其次,哈希表長度的選擇,是一個難點,
二,hash_map
c++的hash_map其原理差別不大,我們介紹一下java里面的hash_map是如何實現的,
原理: 在jdk8,對hash_map進行了優化,使用鏈表和紅黑樹兩種方式對接哈希表的桶,我們都知道,鏈表構建很簡單,而紅黑樹,一個結點就會多4個區域,也存在空間的浪費,但是查詢效率很多,所以為了達到最好的效果,設置了一個閾值,比如說8,捅下的結點數,如果超過了這個值,那么就會轉為為紅黑樹存放,這樣就大大的優化了速度。
功能:
基本功能