lfu(least frequently used):淘汰最近訪問頻率最小的元素。
設計思路:兩個雙向鍊錶,橫向的雙向鍊錶用來統計訪問頻率,縱向的雙向鍊錶,沒出現過的元素出現在橫向鍊錶的頭結點上,如果一直增加沒有訪問,則將元素全部掛到頭結點的下方,縱向形成雙向鍊錶。
橫向鍊錶中統計訪問的頻率,如果增加某個節點的訪問一次,則橫向鍊錶判斷訪問總次數是否存在,如果存在,則將節點放到該次數節點的下方,如果不存在則新建乙個頭結點,將該節點掛到下面。如果有乙個次數下方不再儲存節點,則將該次數在橫向鍊錶中刪去。
public
static
class
node
}public
static
class
lfucache
public
void
addnodefromhead
(node newhead)
public
boolean
isempty()
//刪掉任何乙個節點
public
void
deletenode
(node node)
else
else
if(node == tail)
else
} node.up = null;
node.down = null;}}
//容量
private
int capacity;
private
int size;
//key->node型別,不是次數
private hashmap
records;
//對於任何node,都可以查到他屬於哪個nodelist
private hashmap
heads;
//大結構是nodelist串起來的,現在給出雙向鍊錶的頭部方便查詢
private nodelist headlist;
public
lfucache
(int capacity)
public
void
set(
int key,
int value)
else
node node =
newnode
(key,value,1)
;//如果整個鏈表現在是空的,則新建乙個nodelist
if(headlist == null)
else
else
} records.
put(key,node)
; heads.
put(node.headlist)
; size++;}
}private
void
move
(node node,nodelist oldnodelist)
newlist.last = prelist;
if(headlist == null)
head.
put(node,newlist);}
else
else
newlist.last = prelist;
newlist.next = nextlist;
nextlist.last = newlist;
if(headlist == nextlist)
head.
put(node,newlist);}
}}//當鍊表中資料被拿出時,判斷是否需要刪除整個list
private
boolean
modifyheadlist
(nodelist nodelist)
}else
}return
true;}
return
false;}
public
intget
(int key)
node node = records.
get(key)
; node.times++
; nodelist curnodelist = heads.
get(node)
;move
(node,curnodelist)
;return node.value;
}}
左神演算法筆記(二十) LRU快取演算法實現
準備兩張表,乙個雜湊表,乙個雙向鍊錶。假設a,3存入表中,則map中key還是原始的key,key a,value加工一下,包括a和3.對於雙向鍊錶從尾部加,從頭部出。如果需要將某個元素從拿出,則此時將需要拿出的元素拿出,放到鍊錶的最後,此時,該元素優先順序最高。如果快取大小超過了k,此時將雙向鍊錶...
左神演算法筆記01
對數器異或工具 一些其它的位運算子的操作 簡單理解為 將乙個演算法的所有操作拆成基本操作 常數時間完成的操作 後,計算出操作次數和操作時間 可視為1 的乘積,即操作次數之和。在考慮最差情況時用o 來表示時間複雜度,取最高項來表示。如o n o logn 對n個數進行排列,則最差要進行1 2 3 n ...
左神演算法筆記03
可以是函式遞迴,也可以是迴圈實現。將大的陣列對半分為兩個陣列,每個陣列排好序後再合併為大的陣列。如果使用迴圈實現,要提防整形溢位 應用 最小和問題,若陣列的左邊的乙個數比右邊的某乙個數小,在返回結果加上自身的大小 public static intprocess int arr,int l,int ...