python基於雙向鏈表實現LFU算法
本文實例為大傢分享瞭python實現LFU算法的具體代碼,供大傢參考,具體內容如下
在第一節中實現瞭雙向鏈表DoubleLinkedList類,上一節中基於雙向鏈表實現瞭LRU算法,本節課我們繼續基於雙向鏈表實現LFU(Least frequently used 最不經常使用)算法。
一、重寫Node節點類
構建LFUNode類 繼承自第一節中的Node類,添加freq屬性用來表示節點使用頻率
class LFUNode(Node): def __init__(self, key, value): """ LFU節點 增加頻率屬性 :param key: :param value: """ self.freq = 0 super(LFUNode, self).__init__(key, value)
二、LFU實現
LFU的實現除瞭get和put之外還有一個私有的__update_freq更新節點頻率方法,讀寫某節點時都需要對該節點的頻率屬性進行更新。除瞭map之外新增加一個freq_map來存儲每個頻率下的雙向鏈表,當達到最大容量時移除最小頻率下的頭部的節點。
class LFUCache(object): def __init__(self, capacity=0xffffffff): """ LFU緩存置換算法 最不經常使用 :param capacity: """ self.capacity = capacity self.size = 0 self.map = {} self.freq_map = {} def __update_freq(self, node): """ 更新節點頻率 :param node: :return: """ freq = node.freq # 當前節點所在頻率存在 在當前頻率鏈表中移除當前節點 if freq in self.freq_map: node = self.freq_map[freq].remove(node) # 當前頻率鏈表為空時刪除該頻率鏈表 if self.freq_map[freq].size == 0: del self.freq_map[freq] # 將節點按照新頻率寫入頻率鏈表 freq += 1 node.freq = freq if freq not in self.freq_map: self.freq_map[freq] = DoubleLinkedList() self.freq_map[freq].append(node) return node def get(self, key): """ 獲取元素 :return: """ # 節點不存在 if key not in self.map: return None # 節點存在 更新使用頻率 old_node = self.map.get(key) new_node = self.__update_freq(old_node) self.map[key] = new_node return new_node.value def put(self, key, value): """ 設置元素 :param key: :param value: :return: """ # 節點已存在 更新頻率 if key in self.map: old_node = self.map.get(key) old_node.value = value new_node = self.__update_freq(old_node) self.map[key] = new_node else: # 節點容量達到上限 移除最小頻率鏈表頭部的節點 if self.size >= self.capacity: min_freq = min(self.freq_map) node = self.freq_map[min_freq].pop() del self.map[node.key] self.size -= 1 # 構建新的節點 更新頻率 new_node = LFUNode(key, value) new_node = self.__update_freq(new_node) self.map[key] = new_node self.size += 1 return new_node def print(self): """ 打印當前鏈表 :return: """ for freq, link in self.freq_map.items(): print("frequencies: %d" % freq) link.print()
三、測試邏輯
if __name__ == '__main__': lfu_cache = LFUCache(4) lfu_cache.put(1, 1) lfu_cache.print() lfu_cache.put(2, 2) lfu_cache.print() print(lfu_cache.get(1)) lfu_cache.print() lfu_cache.put(3, 3) lfu_cache.print() lfu_cache.put(4, 4) lfu_cache.print() lfu_cache.put(5, 5) lfu_cache.print() print(lfu_cache.get(2)) lfu_cache.put(4, 400) lfu_cache.print()
測試結果:
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。
推薦閱讀:
- JavaScript雙向鏈表實現LFU緩存算法
- Java實現常用緩存淘汰算法:FIFO、LRU、LFU
- C++ 實現LRU 與 LFU 的緩存算法
- 如何利用Go語言實現LRU Cache
- Java 手寫LRU緩存淘汰算法