golang lru實現

/**
運用你所掌握的數據結構,設計和實現一個  LRU (最近最少使用) 緩存機制。它應該支持如下操做: 獲取數據 get 和 寫入數據 put 。

獲取數據 get(key) - 若是密鑰 (key) 存在於緩存中,則獲取密鑰的值(老是正數),不然返回 -1。
寫入數據 put(key, value) - 若是密鑰不存在,則寫入其數據值。當緩存容量達到上限時,它應該在寫入新數據以前刪除最近最少使用的數據值,從而爲新的數據值留出空間。

進階:

你是否能夠在 O(1) 時間複雜度內完成這兩種操做?

示例:

LRUCache cache = new LRUCache( 2 /* 緩存容量 );

cache.put(1, 1);
cache.put(2, 2);
cache.get(1);       // 返回  1
cache.put(3, 3);    // 該操做會使得密鑰 2 做廢
cache.get(2);       // 返回 -1 (未找到)
cache.put(4, 4);    // 該操做會使得密鑰 1 做廢
cache.get(1);       // 返回 -1 (未找到)
cache.get(3);       // 返回  3
cache.get(4);       // 返回  4

來源:力扣(LeetCode)
連接:https://leetcode-cn.com/problems/lru-cache
著做權歸領釦網絡全部。商業轉載請聯繫官方受權,非商業轉載請註明出處。
*/
type LRUCache struct {
	Cap    int //容量
	Bucket map[int]*Node
	Head   *Node //頭節點
	Tail   *Node //尾節點
}
type Node struct {
	Key  int
	Val  int
	Pre  *Node
	Next *Node
}

func LruConstructor(capacity int) LRUCache {
	return LRUCache{
		Cap:    capacity,
		Bucket: make(map[int]*Node, capacity),
	}
}

func (this *LRUCache) Get(key int) int {
	if item, ok := this.Bucket[key]; ok {
		this.RefreshNode(item)
		return item.Val
	} else {
		return -1
	}
}

func (this *LRUCache) Put(key int, value int) {

	if item, ok := this.Bucket[key]; !ok {
		if len(this.Bucket) >= this.Cap {
			this.RemoveNode(this.Head)
		}
		node := &Node{
			Key:  key,
			Val:  value,
			Pre:  nil,
			Next: nil,
		}
		this.AddNode(node)
		this.Bucket[key] = node
	} else {
		item.Val = value
		this.RefreshNode(item)
	}
}

//添加節點  往表尾添加最近新增的node
func (this *LRUCache) AddNode(node *Node) {

	if this.Tail != nil {
		this.Tail.Next = node
		node.Pre = this.Tail
		node.Next = nil
	}
	this.Tail = node
	if this.Head == nil {
		this.Head = node
		this.Head.Next = nil
	}
	this.Bucket[node.Key] = node
}

func (this *LRUCache) RemoveNode(node *Node) {
	if node == this.Tail {
		this.Tail = this.Tail.Pre
	} else if node == this.Head {
		this.Head = this.Head.Next
	} else {
		node.Pre.Next = node.Next
		node.Next.Pre = node.Pre
	}
	delete(this.Bucket, node.Key)
}

//將已存在的節點移到表尾
func (this *LRUCache) RefreshNode(node *Node) {

	//若是已經在表尾 則直接返回
	if this.Tail == node {
		return
	}
	this.RemoveNode(node)
	this.AddNode(node)
}

func (this *LRUCache) PrintLRU() {

	root := this.Head
	for root != nil {
		fmt.Printf("current node key is[%+v],value is [%+v]\n", root.Key, root.Val)
		root = root.Next
	}
	return
}

複製代碼
相關文章
相關標籤/搜索