手擼LFU快取結構,雜湊表 二維鍊錶

2021-10-25 10:15:28 字數 3218 閱讀 3942

什麼是lfu?

當記憶體不足時,優先刪除被操作次數最少的元素。

雜湊表 + 二維雙向鍊錶

二維鍊錶維護不同訪問次數和相同訪問次數結點集合之間的關係。每一列的雙向鍊錶是所有出現操作次數相同的節點的集合,次數鍊錶的頭節點之間也相互連線的,同樣構成雙向鍊錶。

二維鍊錶的結構:

鍊錶中node結點的設計:

public

static

class

node

}

每一列的雙向鍊錶單獨維護,每列之間也使用雙向指標進行連線:

/**

* 相當於乙個二維的雙向鍊錶,上下鍊錶的是相同次數的結點,左右連線的是不同次數的結點

*/public

static

class

nodelist

//新增乙個節點,放到nodelist的頭部

public

void

addfromhead

(node node)

public

boolean

isempty()

//刪除指定的結點

public

void

deletenode

(node node)

else

else

if(tail == node)

else

}//釋放該結點的所有引用

node.up = null;

node.down = null;

}}

lru設計思路當元素被操作(新增、訪問…)後,將對應的node的times++,然後被操作的結點從原來的列中刪除,移到現在times所在的列。這樣快取中操作次數最少的元素就總是在第一列的第乙個node,當面臨記憶體淘汰時就優先從頭開始刪除。

public

class

lfucache

}/**

* 相當於乙個二維的雙向鍊錶,上下鍊錶的是相同次數的結點,左右連線的是不同次數的結點

*/public

static

class

nodelist

//新增乙個節點,放到nodelist的頭部

public

void

addfromhead

(node node)

public

boolean

isempty()

//刪除指定的結點

public

void

deletenode

(node node)

else

else

if(tail == node)

else

}//釋放該結點的所有引用

node.up = null;

node.down = null;}}

int capacity;

//快取的容量

int size;

//快取中目前的容量大小

hashmap

records;

//記錄key對應的node

hashmap

heads;

//記錄每個node在哪個列中

nodelist headlist;

//記錄第一列,當面臨擴容問題時,刪除第一列的第乙個結點

public

lfucache

(int capacity)

//新增元素

public

void

set(integer key, integer value)

else

node node =

newnode

(key, value,1)

;if(headlist == null)

else

else

} records.

put(key, node)

; heads.

put(node,headlist)

; size++;}

}public

intget

(integer key)

node node = records.

get(key)

; node.times++

; nodelist nodelist = heads.

get(node)

;move

(node, nodelist)

;return node.value;

}//將node從原來的nodelist中刪除,移到++times的nodelist的頭節點

private

void

move

(node node, nodelist oldnodelist)

newlist.last = prenodelist;

if(headlist == null)

heads.

put(node, newlist);}

else

else

else

newlist.last = prenodelist;

newlist.next = nextlist;

nextlist.last = newlist;

heads.

put(node,newlist);}

}}//判斷指定的nodelist中是否還有結點,如果沒有則刪除並且返回true,否則返回false

private

boolean

modifyheadlist

(nodelist nodelist)

}else

}return

true;}

return

false;}

public

static

void

main

(string[

] args)

}

需要對鍊錶的操作的比較熟悉,細節比較繁瑣。寫完不放心的同學可以到lintcode中跑一下哦。

LFU快取策略

example lfucache cache new lfucache 2 capacity cache.put 1,1 cache.put 2,2 cache.get 1 returns 1 cache.put 3,3 evicts key 2 cache.get 2 returns 1 not ...

LFU演算法實現(460 LFU快取)

今天位元組客戶端三面問了這道題,沒做出來。第一,之前沒見過lfu,第二,要求o 1 時間,條件苛刻一點。只能說無緣位元組。言歸正傳,lfu演算法 least frequently used,最近最不經常使用演算法。什麼意思呢 對於每個條目,維護其使用次數cnt 最近使用時間time。cache容量為...

演算法題 LFU快取

題目 設計並實現最不經常使用 lfu 快取的資料結構。它應該支援以下操作 get 和 put。get key 如果鍵存在於快取中,則獲取鍵的值 總是正數 否則返回 1。put key,value 如果鍵不存在,請設定或插入值。當快取達到其容量時,它應該在插入新專案之前,使最不經常使用的專案無效。在此...