基于HashHeap的LFU实现
来源:互联网 发布:贪心算法解决tsp问题 编辑:程序博客网 时间:2024/05/29 19:28
普通heap支持的操作和queue, stack一样,就是push, pop,只是pop出的是最小值,具体点就是add, delMin
hashheap支持一般HashMap的功能,同时维护最小值,和LinkedHashMap是对等的,后者是HashMap加上维护先后关系,hashHeap其实叫HeapedHashMap更科学。
LinkedHashMap -> hashmap + 维护先后关系 -> LRU
HeapedHashMap -> hashmap + 维护最小值 -> LFU
为什么没有叫HeapedHashMap的?因为有了heap,复杂度就被改变了,从O(1)到O(lgn),hash的意义就不在了。而LinkedHashMap 各种操作仍然都是O(1)的,不影响。
进一步分析:HeapedHashMap可以被stl::set取代,因为要处理堆,HeapedHashMap的所有操作都是 O(logN)的,这和stl::set一样,而后者也支持快速得到最小值(*set.begin())
class LFU<K, V> {private static class Counter<V> implements Comparable<Counter<V>> {V data;Integer freq;Counter(V data, Integer freq) {this.data = data;this.freq = freq;}@Overridepublic int compareTo(Counter<V> e) {return this.freq - e.freq;}}int maxSize;HashHeap<K, Counter<V>> hh = new HashHeap<K, Counter<V>>();public LFU(int maxSize) {this.maxSize = maxSize;}public V get(K key) {Counter<V> e = hh.get(key);if (e == null) return null;e.freq++;hh.put(key, e);return e.data;}public void put(K key, V value) {Counter<V> e = hh.get(key);if (e == null) {if (hh.size() == maxSize) {System.out.println("expire " + hh.delMin());}}hh.put(key, new Counter<V>(value, 1));}}
public class HashHeap <K, V extends Comparable<V>> {private static class Entry<K, V extends Comparable<V>> {K key;V value;Entry(K k, V v) {key = k;value = v;}}private Map<K, Integer> addr = new HashMap<K, Integer>();private List<Entry<K, V>> heap = new ArrayList<Entry<K, V>>();public void put(K key, V value) {Integer pos = addr.get(key);if (pos == null) {heap.add(new Entry<K, V>(key, value));addr.put(key, heap.size() - 1);siftUp(heap.size() - 1);}else {Entry<K, V> e = heap.get(pos);V oldValue = e.value;e.value = value;if (value.compareTo(oldValue) > 0) siftDown(pos);else siftUp(pos);}}public V get(K key) {Integer pos = addr.get(key);if (pos == null) return null;return heap.get(pos).value;}public void remove(K key) {Integer pos = addr.get(key);if (pos == null) return;heap.set(pos, heap.get(heap.size() - 1));addr.put(heap.get(pos).key, pos);heap.remove(heap.size() - 1);siftDown(pos);addr.remove(key);}public K delMin() {if (heap.size() == 0) return null;Entry<K, V> e = heap.get(0);remove(e.key);return e.key;}public int size() {return addr.size();}private void swap(int i, int j) {Entry<K, V> temp = heap.get(i);heap.set(i, heap.get(j));heap.set(j, temp);addr.put(heap.get(i).key, i);addr.put(heap.get(j).key, j);}private void siftUp(int i) {while (i > 0 && heap.get(i).value.compareTo(heap.get((i - 1) / 2).value) < 0 ) {swap(i, (i - 1) / 2);i = (i - 1) / 2;}}private void siftDown(int i) {while (2 * i + 1 < heap.size()) {int j = 2 * i + 1;if (j + 1 < heap.size() && heap.get(j + 1).value.compareTo(heap.get(j).value) < 0) ++j;if (heap.get(i).value.compareTo(heap.get(j).value) > 0) {swap(i, j);i = j;}else break;}}}
0 0
- 基于HashHeap的LFU实现
- 基于最少使用频次的LRU,LFU缓存淘汰算法
- 简单的java缓存实现(LRU,LFU,FIFO)
- java实现时间复杂度O(1)的LFU缓存
- LRU、LFU算法java实现
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- LFU与LRU的不同
- LRU和LFU的区别
- LRU和LFU的区别
- LRU和LFU的区别
- glibc-2.15 : fopen 源码
- 目标检测“DPMs are CNNs”
- PASSION之Linux命令详解
- 小巧而又强大的翻译神器--QTranslate
- Java嵌套类
- 基于HashHeap的LFU实现
- js typeof
- swift 初级 断言
- Ubuntu 安装mysql和简单操作
- 【L“”】无法将参数从“const char”转换为“LPCWSTR”
- 删除链表中倒数第n个节点(LintCode)
- 常用的排序算法的时间复杂度和空间复杂度
- 仿微博个人主页效果
- 度量快速开发平台中集成登录CS程序的思路设想