FIFO、LRU与LFU
双向链表的原理与实践
- 介绍
- 单向链表
- 双向链表
-
双向链表有什么好处
- 可以快速找到一个节点的下一个节点
- 可以快速找到一个节点的上一个节点
- 可以快速去掉链表中的某一个节点
-
实现双向链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
#! -*- encoding=utf-8 -*- class Node: def __init__(self, key, value): self.key = key self.value = value self.prev = None self.next = None def __str__(self): val = '{%d: %d}' % (self.key, self.value) return val def __repr__(self): val = '{%d: %d}' % (self.key, self.value) return val class DoubleLinkedList: def __init__(self, capacity=0xffff): self.capacity = capacity self.head = None self.tail = None self.size = 0 # 从头部添加 def __add_head(self, node): if not self.head: self.head = node self.tail = node self.head.next = None self.head.prev = None else: node.next = self.head self.head.prev = node self.head = node self.head.prev = None self.size += 1 return node # 从尾部添加 def __add_tail(self, node): if not self.tail: self.tail = node self.head = node self.tail.next = None self.tail.prev = None else: self.tail.next = node node.prev = self.tail self.tail = node self.tail.next = None self.size += 1 return node # 从尾部删除 def __del_tail(self): if not self.tail: return node = self.tail if node.prev: self.tail = node.prev self.tail.next = None else: self.tail = self.head = None self.size -= 1 return node # 从头部删除 def __del_head(self): if not self.head: return node = self.head if self.head.next: self.head.next.prev = None self.head = self.head.next else: self.head = self.tail = None self.size -= 1 return node # 任意节点删除 def __remove(self, node): # 如果node=None, 默认删除尾部节点 if not node: node = self.tail if node == self.tail: self.__del_tail() elif node == self.head: self.__del_head() else: node.prev.next = node.next node.next.prev = node.prev self.size -= 1 return node def pop(self): return self.__del_head() def append(self, node): return self.__add_tail(node) def append_front(self, node): return self.__add_head(node) def remove(self, node=None): return self.__remove(node) def print(self): p = self.head line = '' while p: line += '%s' % (p) p = p.next if p: line += '->' print(line) if __name__ == '__main__': l = DoubleLinkedList(10) nodes = [] for i in range(10): node = Node(i, i) nodes.append(node) l.append(nodes[0]) l.print() l.append(nodes[1]) l.print() l.pop() l.print() l.append(nodes[2]) l.print() l.append_front(nodes[3]) l.print() l.append(nodes[4]) l.print() l.remove(nodes[2]) l.print() l.remove() l.print()
实现FIFO缓存置换算法
-
先进先出算法(FIFO)
- 把高速缓存看做是一个先进先出的队列
- 优先替换最先进入队列的字块
-
代码示例
实现LRU缓存置换算法
-
最近最少使用算法(LRU)
- 优先淘汰一段时间内没有使用的字块
- 有多种实现方法,一般使用双向链表
- 把当前访问节点置于链表前面(保证链表头部节点是最近使用的)
-
代码示例
实现LFU缓存置换算法
- 最不经常使用算法(LFU)
- 优先淘汰最不经常使用的字块
- 需要额外的空间记录字块的使用频率
- 示例代码