數據結構與算法之美學習筆記:第二十講

1、LRU 緩存淘汰算法

一、回顧LRU淘汰算法 

二、一個緩存主要包含哪些操做

三、單獨使用鏈表和組合使用對比

 

四、hnext的做用

五、如何把時間複雜度降到O(1)

在緩存中查找一個數據java

從緩存中刪除一個數據算法

往緩存中添加一個數據緩存

2、Redis有序集合

一、有序集合

二、有序集合的操做

三、單獨和組合使用比較

 

3、Java LinkedHashMap

若是你熟悉 Java,那你幾乎每天會用到這個容器。咱們以前講HashMap 底層是經過散列表這種數據結構實現的。而 LinkedHashMap 前面比 HashMap 多了一Linked」,數據結構

這裏的「Linked」是否是說,LinkedHashMap 是一個經過鏈表法解決散列衝突的散列表呢?函數

實際上,LinkedHashMap 並無這麼簡單,其中的「Linked」也並不只僅表明它是經過鏈表法解決散列衝突的。關於這一點,在我是初學者的時候,也誤解了好久3d

咱們先來看一段代碼。你以爲這段代碼會以什麼樣的順序打印 3,1,5,2 這幾個 key 呢?緣由又是什麼呢?blog

HashMap<Integer, Integer> m = new LinkedHashMap<>();
m.put(3, 11);
m.put(1, 12);
m.put(5, 23);
m.put(2, 22);

for (Map.Entry e : m.entrySet()) {
  System.out.println(e.getKey());
}

我先告訴你答案,上面的代碼 會按照數據插入的順序依次來打印,也就是說,打印順序就是
,你有沒有以爲奇怪?散列表中的數據是通過散列幻術打亂以後無規律存儲的,
這裏是如何實現按照數據的插入順序來遍歷數據,你能夠看下面這段代碼:排序

你可能已經猜到,也是經過散列表和鏈表組合在一塊兒實現的,實際上,它不只支持按照插入順序遍歷數據
還支持按照問順序來遍歷數據,你能夠看下這段代碼get

// 10 是初始大小,0.75 是裝載因子,true 是表示按照訪問時間排序
HashMap<Integer, Integer> m = new LinkedHashMap<>(10, 0.75f, true);
m.put(3, 11);
m.put(1, 12);
m.put(5, 23);
m.put(2, 22);

m.put(3, 26);
m.get(5);

for (Map.Entry e : m.entrySet()) {
  System.out.println(e.getKey());
}

這段代碼的結果是1,2,3,5我來抉剔分析一下,爲何這段代碼會按照這樣的順序來打印class

每次調用put()函數往 中添加數據的時候,都會將數據添加到鏈表的尾部,因此,在前四個操做完成以後,鏈表中的數據是下面這樣的

在第 8 行代碼中,再次將鍵值爲 3 的數據放入到 LinkedHashMap 的時候,會先查找這個鍵值是否已經有了,

而後,再將已經存在的 (3,11) 刪除,而且將新的 (3,26) 放到鏈表的尾部。因此,這個時候鏈表中的數據就是下面這樣:

當第 9 行代碼訪問到 key 爲 5 的數據的時候,咱們將被訪問到的數據移動到鏈表的尾部。因此,第 9 行代碼以後,鏈表中的數據是下面這樣:

因此,最後打印出來的數據是1,2,3,5從上面的分析,你有沒有發現,按照訪問時間排序的,自己就是一個支持淘汰策略的緩存系統?實際上,

他們兩個的實現原理也是如出一轍的,我也就再也不囉嗦了

 

我如今來總結一下,實際上,LinkedHashMap 是經過雙向鏈表和散列表這兩種數據結構組合實現的LinkedHashMap 中的「Linked」其實是指的雙向鏈表,並不是指用鏈表法解決散列衝突

4、解答開篇 & 內容小結

一、散列表

二、組合使用

三、散列表小結

相關文章
相關標籤/搜索