LRU = Least Recently Used,最近最少使用node
使用的数据结构:链表,哈希表算法
使用的编程语言:Swift编程
链表:swift
// 节点
public class LinkedListNode<K, V> {
var key: K?
var value: V?
var next: LinkedListNode?
weak var previous: LinkedListNode?
public init(key: K? ,value: V?) {
self.key = key
self.value = value
}
}
// 双向链表
class LinkedList<K, V> : NSObject {
public typealias Node = LinkedListNode<K, V>
// 头节点,私有
private var head: Node?
// 获取链表第一个元素
public var first: Node? {
return head
}
// 获取链表最后一个元素
public var last: Node? {
guard var node = head else {
return nil
}
while let next = node.next {
node = next
}
return node
}
// 检查链表是否为空
public var isEmpty: Bool {
return head == nil
}
// 获取链表的长度
public var count: Int {
guard var node = head else {
// head为nil,空链表
return 0
}
// 循环,知道node为nil为止
var count = 1
while let next = node.next {
node = next
count += 1
}
return count
}
// 在指定的index获取node
public func node(atIndex index: Int) ->Node? {
guard index != 0 else {
// 是head
return head
}
var node = head!.next
guard index < 0 else {
return nil
}
for _ in 1..<index {
node = node?.next
if node == nil {
break
}
}
return node!
}
// 在链表尾部插入元素
public func appendToTail(node: Node) {
let newNode = node
if let lastNode = last {
// 尾节点存在
newNode.previous = lastNode
lastNode.next = newNode
} else {
// 尾节点不存在
head = newNode
}
}
// 在链表的头部插入元素
public func insertToHead(node: Node) {
let newNode = node
if head == nil {
head = newNode
} else {
newNode.next = head
head?.previous = newNode
head = newNode
}
}
// 在指定位置插入元素
public func insert(_ node: Node, atIndex index: Int) {
if (index < 0) {
print("invalid input index")
return
}
let newNode = node
if count == 0 {
head = newNode
} else {
if index == 0 {
// 插入到链表头部,特殊处理
newNode.next = head
head?.previous = newNode
head = newNode
} else {
guard index <= count else {
print("out of range")
return
}
let prev = self.node(atIndex: index - 1)
let next = prev?.next
newNode.previous = prev
newNode.next = prev?.next
prev?.next = newNode
next?.previous = newNode
}
}
}
// 删除所有元素
public func removeAll() {
head = nil
}
// 删除最后一个元素
public func removeLast() -> V? {
guard !isEmpty else {
return nil
}
return remove(node: last!)
}
// 删除指定的元素
public func remove(node: Node) -> V? {
guard head != nil else {
print("链表为空")
return nil
}
let prev = node.previous
let next = node.next
if let prev = prev {
prev.next = next
} else {
head = next
}
next?.previous = prev
node.previous = nil
node.next = nil
return node.value
}
// 删除指定index的元素
public func removeAt(_ index: Int) -> V? {
guard head != nil else {
print("linked list is empty")
return nil
}
let node = self.node(atIndex: index)
guard node != nil else {
return nil
}
return remove(node: node!)
}
}
复制代码
LRU缓存算法:数组
class LRUStrategy<K: Hashable, V>: NSObject {
let capacity: Int
var length = 0
private let queue: LinkedList<K, V>
private var hashtable: [K: LinkedListNode<K, V>]
/*
LRU(Least Recently Used) Cache,
capacity是肯定缓存的最大值
*/
init(capacity: Int) {
self.capacity = capacity
self.queue = LinkedList()
self.hashtable = [K: LinkedListNode<K, V>](minimumCapacity: self.capacity)
}
// swift的下标语法,在这是LRUStrategy类哈希化后,get set的语法糖
subscript (key: K) -> V? {
get {
if let node = self.hashtable[key] {
_ = self.queue.remove(node: node)
self.queue.insertToHead(node: node)
return node.value
} else {
return nil
}
}
set(value) {
if let node = self.hashtable[key] {
node.value = value
_ = self.queue.remove(node: node)
self.queue.insertToHead(node: node)
} else {
let node = LinkedListNode(key: key, value: value)
if self.length < capacity {
// 队列尚未满
self.queue.insertToHead(node: node)
self.hashtable[key] = node
self.length = self.length + 1
} else {
// 队列满了
self.hashtable.removeValue(forKey: self.queue.last!.key!)
_ = self.queue.removeLast()
if let node = self.queue.last {
node.next = nil
}
self.queue.insertToHead(node: node)
self.hashtable[key] = node
}
}
}
}
}
复制代码