LRU
最近最久未使用 ,这里的最久是通过隐式体现的 ,是给一个序列,使用一次,就放前面,没使用就不动。这样的话越久没使用的就越在后面 可以想象看
这里的使用一次 指的是 访问一次,更新一次。
注意控制大小,并且在插入元素 ,删除元素的时候 缓存体积也变一下
问:
为什么用双向链表?
答:
因为在删除的时候可以找到下一次即将删除的节点。并之一删除到尾部的时候注意更新 尾结点
代码如下 : 可以直接运行 看着多, 其实不难, get, put 里面是逻辑,node_list 里有双向链表的方法。
# coding=utf8
# __author__ = 'kc'
# @File : lru.py
# @Software: PyCharm
class Node(object):
def __init__(self, val, l, r, k):
self.parent = l
self._next = r
self.val = val
self.k = k
class NodeList(object):
"""双向链表"""
def __init__(self):
self.tail = None
self.head = Node("", None, None, "")
def del_item(self, node):
"""
从链表中删除对应的node
:param node: Node 类型
:return:
"""
parent = node.parent
_next = node._next
parent._next = _next
if _next:
_next.parent = parent
# 最后一个元素
if node._next == None:
self.tail = parent
# print self.tail.val
node._next = None
node.parent = None
return node
def insert_head(self, node):
"""
在头部添加
:param item: 插入到头部
:return:
"""
# 更新tail
if self.head._next == None:
self.tail = node
_tmp = self.head._next
if _tmp:
_tmp.parent = node
node._next = _tmp
node.parent = self.head
self.head._next = node
return node
def del_tail(self):
tail = self.del_item(self.tail)
return tail
def __str__(self):
r = []
_head = self.head._next
while _head:
r.append(str(_head.val))
_head = _head._next
return ", ".join(r)
class LRUCache(object):
def __init__(self, capacity):
"""
:type capacity: int
"""
self.capacity = capacity
self.size = 0
self.data = {}
self.nl = NodeList()
def get(self, key):
"""
:type key: int
:rtype: int
"""
# print self.nl
node = self.data.get(key)
if node:
node = self.nl.del_item(node)
self.nl.insert_head(node)
return node.val
else:
return -1
def put(self, key, value):
"""
:type key: int
:type value: int
:rtype: None
"""
# node = self.data.get(key)
# if node:
# node = self.nl.del_item(node)
# self.size -= 1
# if self.get(key) != -1:
# self.nl.del_head()
node = self.data.get(key)
if node:
self.nl.del_item(node)
self.size -= 1
self.data.pop(key)
node = self.nl.insert_head(Node(value, None, None, key))
self.data[key] = node
self.size += 1
if self.size > self.capacity:
tail = self.nl.del_tail()
self.data.pop(tail.k)
self.size -= 1
# print self.nl
print "下面是链表的值, 每次操作都会打印"
print "--" * 20
lru = LRUCache(2)
print "这里是缓存的值:", lru.nl
lru.put(2, 2)
print "这里是缓存的值:", lru.nl
lru.put(1, 4)
print "这里是缓存的值:", lru.nl
lru.get(2)
print "这里是缓存的值:", lru.nl
lru.put(3, 5)
print "这里是缓存的值:", lru.nl
lru.put(2, 3)
print "这里是缓存的值:", lru.nl
lru.put(1, 1)
print "这里是缓存的值:", lru.nl