golang實現LRU演算法
阿新 • • 發佈:2022-02-13
golang實現LRU演算法
Least Recently used
本文僅列出完成 LeetCode146.LRU快取的思路
實現:
- 雜湊表:鍵為關鍵字key,值為*DLinkNode,對映對應連結串列中的節點
- 雙向連結串列:靠近頭部的元素是最近使用的,靠近尾部則是最久未使用的
實現LRU並不難,建議先把演算法的各個函式的框架先列好,再去敲程式碼!!
結構:
//LRUCache定義 type LRUCache struct { size int capacity int cache map[int]*DLinkNode head, tail *DLinkNode } //雙向連結串列節點 type DLinkNode struct { key,value int pre, next *DLinkNode }
功能:
//快取實現的功能 //如果關鍵字 key 存在於快取中,則返回關鍵字的值,否則返回 -1 。 func (this *LRUCache) Get(key int) //如果關鍵字key 已經存在,則變更其資料值value ;如果不存在,則向快取中插入該組key-value 。如果插入操作導致關鍵字數量超過capacity ,則應該 逐出最久未使用的關鍵字 func (this *LRUCache) Put(key int, value int) //一些連結串列的操作 //初始化一個新節點 func initDLinkedNode(key, value int) *DLinkNode //更新到鏈頭,用於key命中的情況下,不改變快取的size func (this *LRUCache) UpdateToHead(node *DLinkNode) //刪除鏈尾元素 func (this *LRUCache) DeleteLast() //新增新元素,用於key未命中時,size+1 func (this *LRUCache) InsertNewHead(node *DLinkNode)
以下附上完整程式碼
type LRUCache struct { size int capacity int cache map[int]*DLinkNode Head, Tail *DLinkNode } type DLinkNode struct { key,value int Pre, Next *DLinkNode } func InitDlinkNode(key, value int) *DLinkNode { return &DLinkNode{key,value,nil,nil} } func Constructor(capacity int) LRUCache { l := LRUCache{ 0, capacity, map[int]*DLinkNode{}, InitDlinkNode(0, 0), InitDlinkNode(0, 0), } l.Head.Next = l.Tail l.Tail.Pre = l.Head return l } func (this *LRUCache) Get(key int) int { if _,ok := this.cache[key];!ok { return -1 } node := this.cache[key] this.UpdateToHead(node) return node.value } func (this *LRUCache) Put(key int, value int) { if _,ok := this.cache[key];!ok { node := InitDlinkNode(key, value) for this.size >= this.capacity { this.DeleteLast() } this.cache[key] = node this.InsertNewHead(node) }else { node := this.cache[key] node.value = value this.UpdateToHead(node) } } func (this *LRUCache) UpdateToHead(node *DLinkNode) { node.Pre.Next = node.Next node.Next.Pre = node.Pre temp := this.Head.Next this.Head.Next = node node.Pre = this.Head node.Next = temp temp.Pre = node } func (this *LRUCache) DeleteLast() { node := this.Tail.Pre this.Tail.Pre = node.Pre node.Pre.Next = node.Next node.Pre = nil node.Next = nil this.size-- delete(this.cache, node.key) } func (this *LRUCache) InsertNewHead(node *DLinkNode) { temp := this.Head.Next this.Head.Next = node node.Pre = this.Head temp.Pre = node node.Next = temp this.size++ }