1. 程式人生 > >LRU Cache(go)

LRU Cache(go)

實現方法:採用雙向連結串列和map結構進行實現

程式碼如下:

type Node struct {
	key   int
	value int
	next  *Node
	pre   *Node
}

type LRUCache struct {
	capacity int
	count    int
	head     *Node
	tail     *Node
	hash     map[int]*Node
}

func ConstructorLRU(capacity int) LRUCache {
	return LRUCache{capacity: capacity, hash: make(map[int]*Node)}
}

func (this *LRUCache) Get(key int) int {
	nd, ok := this.hash[key]
	if ok {
		if nd.pre == nil && nd.next == nil {
			this.head = nil
			this.tail = nil
		} else if nd.pre == nil && nd.next != nil {
			this.head = nd.next
			this.head.pre = nil
		} else if nd.pre != nil && nd.next == nil {
			this.tail = nd.pre
			this.tail.next = nil
		} else {
			nd.next.pre = nd.pre
			nd.pre.next = nd.next
		}
		this.count --
		this.insertIntoHead(nd)
		return nd.value
	}
	return -1
}


func (this *LRUCache) Put(key int, value int)  {
	nd, ok := this.hash[key]
	tempNode := &Node{key:key, value:value}
	if ok {
		nd.value = value
		tempNode = nd
		if nd.pre == nil && nd.next == nil {  // 當前連結串列中只有一個節點
			this.head = nil
			this.tail = nil
		} else if nd.pre == nil && nd.next != nil { // 插入的節點在連結串列中,且是頭節點
			this.head = nd.next
			this.head.pre = nil
		} else if nd.pre != nil && nd.next == nil { // 插入的節點在連結串列中,且是尾節點
			this.tail = nd.pre
			this.tail.next = nil
		} else {
			nd.next.pre = nd.pre
			nd.pre.next = nd.next
		}
		this.count --
	}
	this.insertIntoHead(tempNode)
	if this.count > this.capacity {
		this.removeFromTail()
	}
}

// 向連結串列中插入頭節點
func (this *LRUCache) insertIntoHead(node *Node) {
	if nil == this.head {
		node.pre = nil
		node.next = nil
		this.head = node
		this.tail = node
	} else {
		this.head.pre = node
		node.next = this.head
		node.pre = nil
		this.head = node
	}
	this.hash[node.key] = node
	this.count ++
}

// 刪除連結串列中的尾節點
func (this *LRUCache) removeFromTail() {
	if nil == this.tail || nil == this.tail.pre {
		this.head = nil
		this.tail = nil
	} else {
		delete(this.hash, this.tail.key)
		this.tail = this.tail.pre
		this.tail.next = nil
	}
	this.count --
}