LRU 的实现 双向链表和字典 python
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