为了账号安全,请及时绑定邮箱和手机立即绑定

LRU Cache的原理和python的实现

标签:
Python

LRU Cache的原理和python的实现

LRU的原理

LRU(Least Recently Used)即最近最少使用。 操作系统中一种内存管理的页面置换算法,主要用于找出内存中较久时间没有使用的内存块,将其移出内存从而为新数据提供空间。此算法的前提是认为:当一个数据被访问的越频繁,则这个数据在未来被访问的概率就越高。

LRU算法其实就是按照使用顺序将元素倒叙排列,在有限的存储空间中,若空间满时,删除最后的元素(即最久没有使用的元素)。若想实现高效实现这个算法,使get和set都能O(1)的效率,需要一个有序的字典。

LRU的Python实现(库函数版)

首先实现一个双向链表, 没啥好说的,简单实现一下:
class Node:

    def __init__(self, data, _pre=None, _next=None):        self.data = data        self._pre = _pre        self._next = _next    def __str__(self):        return str(self.data)class DoublyLink:

    def __init__(self):        self.tail = None        self.head = None        self.size = 0

    def insert(self, data):        if isinstance(data, Node):

            tmp_node = data        else:

            tmp_node = Node(data)        if self.size == 0:            self.tail = tmp_node            self.head = self.tail        else:

            self.head._pre = tmp_node

            tmp_node._next = self.head            self.head = tmp_node        self.size += 1

        return tmp_node    def remove(self, node):        if node == self.head:

            self.head._next._pre = None            self.head = self.head._next

        elif node == self.tail:

            self.tail._pre._next = None            self.tail = self.tail._pre        else:

            node._pre._next = node._next

            node._next._pre = node._pre        self.size -= 1

    def __str__(self):

        str_text = ""

        cur_node = self.head        while cur_node != None:

            str_text += cur_node.data + " "

            cur_node = cur_node._next        return str_text
实现LRU算法
  • 插入数据时:若空间满了,则删除链表尾部元素,在进行插入

  • 查询数据时:先把数据删除,再重新插入数据,保证了元素的顺序是按照访问顺序排列

class LRUCache:

    def __init__(self, size):        self.size = size        self.hash_map = dict()        self.link = DoublyLink()    def set(self, key, value):        if self.size == self.link.size:

            self.link.remove(self.link.tail)        if key in self.hash_map:

            self.link.remove(self.hash_map.get(key))

        tmp_node = self.link.insert(value)        self.hash_map.__setitem__(key, tmp_node)    def get(self, key):

        tmp_node = self.hash_map.get(key)        self.link.remove(tmp_node)        self.link.insert(tmp_node)        return tmp_node.data
测试代码
r = LRUCache(3)

r.set("1", "1")

r.set("2", "2")

r.set("3", "3")

print r.link

r.get("1")

print r.link

r.set("4", "4")

print r.link>> 3 2 1>> 1 3 2>> 4 1 3

LRU的Python实现(OrderedDict)

OrderedDict的本质就是一个有序的dict,其实现也是通过一个dict+双向链表
from collections import OrderedDictclass LRUCache:

    def __init__(self, size):        self.size = size        self.linked_map = OrderedDict()    def set(self, key, value):        if key in self.linked_map:

            self.linked_map.pop(key)        if self.size == len(self.linked_map):            self.linked_map.popitem(last=False)        self.linked_map.update({key: value})    def get(self, key):

        value = self.linked_map.get(key)        self.linked_map.pop(key)        self.linked_map.update({key: value})        return value
测试代码
r = LRUCache(3)

r.set("1", "1")

r.set("2", "2")

r.set("3", "3")

print r.linked_map

r.get("1")

print r.linked_map

r.set("4", "4")

print r.linked_map>> OrderedDict([('1', '1'), ('2', '2'), ('3', '3')])>> OrderedDict([('2', '2'), ('3', '3'), ('1', '1')])>> OrderedDict([('3', '3'), ('1', '1'), ('4', '4')])



作者:NeilShao
链接:https://www.jianshu.com/p/e41ec08e4aa6


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消