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
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值