其他题目---设计可以变更的缓存结构
来源:互联网 发布:嵌入式结构 社会网络 编辑:程序博客网 时间:2024/04/28 01:47
【题目】
设计一种缓存结构,该结构在构造时确定大小,假设大小为K,并有两个功能:
- set(key, value):将记录(key, value)插入该结构
- get(key):返回key对应的value值
【要求】
- set和get的时间复杂度为O(1)
- 某个key的set或get操作一旦发生,认为这个key的记录成了最经常使用的
- 当缓存的大小超过K时,移除最不经常使用的记录,即set或get最久远的
【基本思路】
这种缓存结构可以由双端队列与哈希表结合的方式实现。首先实现一个基本的双向链表节点结构,如下:
#python3.5class Node: def __init__(self, value): self.value = value self.pre = None self.next = None
根据双向链表节点结构Node,实现一种双向链表结构DoubleLinkedList,在该结构中优先级最低的是头节点head,优先级最高的是尾节点Tail。这个结构有以下三种操作:
- addNode。加入一个节点,并将该节点设置成链表的尾部
- moveNodeToTail。对链表中的任意一个节点,可以分离出来并放到整个链表的尾部。
- removeHead。移除链表的头节点,并将head设置为head.next。
具体实现如下:
class DoubleLinkedList: def __init__(self): self.head = None self.tail = None def addNode(self, newNode): if newNode == None: return if self.head == None: self.head = newNode self.tail = newNode else: self.tail.next = newNode newNode.pre = self.tail self.tail = newNode def moveNodeToTail(self, node): if node == None: return if node == self.tail: return if node == self.head: self.head = node.next self.head.pre = None else: node.pre.next = node.next node.next.pre = node.pre self.tail.next = node node.next = None node.pre = self.tail self.tail = node def removeHead(self): if self.head == None: return None res = self.head if self.head == self.tail: self.head == None self.tail == None else: self.head = res.next self.head.pre = None res.next = None return res
最后实现最终的缓冲结构。如何把记录之间按照“访问经常度”来排序,就是上文提到的DoubleLinkedList结构。一旦有新的记录,直接放到链表的尾部。一旦获得(get)或设置(set)一个记录,就直接将该key对应的node调整到链表尾部。cache一旦满了,就删除链表的头节点所表示的记录。
为了得到key -> node以及node -> key的关系,使用两个哈希表来建立两者之间的映射关系。
【代码实现】
#python3.5class Node: def __init__(self, value): self.value = value self.pre = None self.next = Noneclass DoubleLinkedList: def __init__(self): self.head = None self.tail = None def addNode(self, newNode): if newNode == None: return if self.head == None: self.head = newNode self.tail = newNode else: self.tail.next = newNode newNode.pre = self.tail self.tail = newNode def moveNodeToTail(self, node): if node == None: return if node == self.tail: return if node == self.head: self.head = node.next self.head.pre = None else: node.pre.next = node.next node.next.pre = node.pre self.tail.next = node node.next = None node.pre = self.tail self.tail = node def removeHead(self): if self.head == None: return None res = self.head if self.head == self.tail: self.head == None self.tail == None else: self.head = res.next self.head.pre = None res.next = None return resclass MyCache: def __init__(self, capacity): self.nodeKeyMap = {} self.keyNodeMap = {} self.capacity = capacity self.nodeList = DoubleLinkedList() def get(self, key): if key in self.keyNodeMap: res = self.keyNodeMap[key] self.nodeList.moveNodeToTail(res) return res.value return None def set(self, key, value): if key in self.keyNodeMap: node = self.keyNodeMap[key] node.value = value self.nodeList.moveNodeToTail(node) else: node = Node(value) self.keyNodeMap[key] = node self.nodeKeyMap[node] = key self.nodeList.addNode(node) if len(self.keyNodeMap) == self.capacity + 1: self.removeMostUnusedCache() def removeMostUnusedCache(self): node = self.nodeList.removeHead() key = self.nodeKeyMap[node] del self.keyNodeMap[key] del self.nodeKeyMap[node]
阅读全文
2 0
- 其他题目---设计可以变更的缓存结构
- 其他题目---设计RandomPool结构
- 其他题目---设计一个没有扩容负担的堆结构
- 后期的设计变更
- 变更设计的流程
- 其他题目---设计有setAll功能的哈希表
- 【题目6】如何设计一个可以获取最小值的栈
- iOS之UIView的层次结构变更
- 关于定义一个结构体可以被其他的源文件使用
- js 变更表结构
- 表结构变更操作
- 其他题目---有关阶乘的两个问题
- 其他题目---随时找到数据流的中位数
- 其他题目---出现次数的TopK问题
- 题目更改 VS 需求变更
- 关于变更设计
- 关于数据库的变更设计的思考随笔
- 良好的设计是应对需求变更的最佳方法
- 可跨域的单点登录(SSO)实现方案【附.net代码】
- 关于clear和浮动
- Linux的单用户模式、救援模式、克隆虚拟机、机器相互登录
- 使用github+hexo搭建个人免费博客
- Python
- 其他题目---设计可以变更的缓存结构
- Maven打包方式,以及jar包冲突问题的解决方法
- 3、Python 处理 JSON 数据
- sqlplus 执行报错
- 支持备份/还原win10系统的分区工具DiskGenius v4.9.3专业版下载+序列号注册文件激活教程
- flume 性能优化
- 欢迎使用CSDN-markdown编辑器
- 游戏开发中的设计模式——1.状态模式
- 游戏背景加入