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
}
}
}
}
}
複製代碼