这是我参与更文挑战的第23天,活动详情查看: 更文挑战node
运用你所掌握的数据结构,设计和实现一个
LRU
(最近最少使用) 缓存机制 。 实现LRUCache
类:缓存
LRUCache(int capacity)
以正整数做为容量 capacity 初始化LRU
缓存 int get(int key) 若是关键字 key 存在于缓存中,则返回关键字的值,不然返回 -1 。 void put(int key, int value) 若是关键字已经存在,则变动其数据值;若是关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据以前删除最久未使用的数据值,从而为新的数据值留出空间。markdown进阶:你是否能够在 O(1) 时间复杂度内完成这两种操做?数据结构
LinkedHashMap
LinkedHashMap
不熟悉的朋友们能够简单的将它理解成HashMap
。 下图展现了HashMap
的存储结构LinkedHashMap
只是多了一条链表串起里面的元素LinkedHashMap
是按照顺序存储的。可是LinkedHahsMap
也没法作到按照使用频率进行排序啊?你们都知道他是按照添加顺序排序的!!!LinkedHashMap
*改造LinkedHashMap
的确没法知足状况,可是咱们稍微看下源码可以发如今put以后都会执行下afterNodeInsertion
这个方法。这也是HashMap
留给LinkedHashMap
作的扩展!removeNode
就是将最前面的数据。想要进入这个方法就须要removeEldestEntry
判断。LinkedHashMap
默认是false . 因此咱们只须要重写他就好了。可是仍是在get值的时候如何保值在最后面呢?咱们仔细看下源码就可以发如今get
中有这个一个方法afterNodeAccess
。他的做用就是将get的元素移位值后面。正好符合咱们LRU
的策略特征LinkedHashMap
就很是容易的实现了LRU策略!可是本题的意思是想考察咱们本身是如何实现的,而不是巧妙对现有的工具改造的!不过上面对LinkedHashMap
的确改造的很巧这是不能否认的!下面咱们就尝试本身来实现下这种方式!工具
首先咱们须要肯定须要用到Hash结合链表来实现。Hash咱们天然使用HashMap
来存储数据为的就是方便定位数据。定位到数据就须要操做链表将数据实时移位值链表尾部,每次淘汰是将链表首位移除既可。为了方便咱们操做链表这里的链表确定是双链表的!oop
preNode
,nextNode
分别指向先后节点方法名 | 做用 |
---|---|
addToTail | 将节点添加值链表尾部 |
moveToTail | 将已经存在于链表中的节点移动到链表的尾部 |
removeHeadNode | 删除链表中第一个节点,注意是边界节点后第一个节点 |