继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

LRU Cache的原理和python的实现

慕标5832272
关注TA
已关注
手记 1071
粉丝 228
获赞 996

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


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP