LRU算法的简单实现

简介:
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
143
144
145
146
147
148
149
150
package  com.hanchao.test0809;
 
import  java.util.Hashtable;
 
public  class  LRUCache {  
     /** 
      * 链表节点 
      * @author Administrator 
      * 
      */  
     class  CacheNode {  
         CacheNode prev; //前一节点  
         CacheNode next; //后一节点  
         Object value; //值  
         Object key; //键  
         CacheNode() {  
         }  
     }  
     
     private  int  cacheSize;  
     private  Hashtable nodes; //缓存容器  
     private  int  currentSize;  
     private  CacheNode first; //链表头  
     private  CacheNode last; //链表尾  
   
     public  LRUCache( int  i) {  
         currentSize =  0 ;  
         cacheSize = i;  
         nodes =  new  Hashtable(i); //缓存容器  
     }  
       
     /** 
      * 获取缓存中对象 
      * @param key 
      * @return 
      */  
     public  Object get(Object key) {  
         CacheNode node = (CacheNode) nodes.get(key);  
         if  (node !=  null ) {  
             moveToHead(node);  
             return  node.value;  
         }  else  {  
             return  null ;  
         }  
     }  
       
     /** 
      * 添加缓存 
      * @param key 
      * @param value 
      */  
     public  void  put(Object key, Object value) {  
         CacheNode node = (CacheNode) nodes.get(key);  
           
         if  (node ==  null ) {  
             //缓存容器是否已经超过大小.  
             if  (currentSize >= cacheSize) {  
                 if  (last !=  null ) //将最少使用的删除  
                     nodes.remove(last.key);  
                 removeLast();  
             }  else  {  
                 currentSize++;  
             }  
               
             node =  new  CacheNode();  
         }  
         node.value = value;  
         node.key = key;  
         //将最新使用的节点放到链表头,表示最新使用的.  
         moveToHead(node);  
         nodes.put(key, node);  
     }  
   
     /** 
      * 将缓存删除 
      * @param key 
      * @return 
      */  
     public  Object remove(Object key) {  
         CacheNode node = (CacheNode) nodes.get(key);  
         if  (node !=  null ) {  
             if  (node.prev !=  null ) {  
                 node.prev.next = node.next;  
             }  
             if  (node.next !=  null ) {  
                 node.next.prev = node.prev;  
             }  
             if  (last == node)  
                 last = node.prev;  
             if  (first == node)  
                 first = node.next;  
         }  
         return  node;  
     }  
   
     public  void  clear() {  
         first =  null ;  
         last =  null ;  
     }  
   
     /** 
      * 删除链表尾部节点 
      *  表示 删除最少使用的缓存对象 
      */  
     private  void  removeLast() {  
         //链表尾不为空,则将链表尾指向null. 删除连表尾(删除最少使用的缓存对象)  
         if  (last !=  null ) {  
             if  (last.prev !=  null )  
                 last.prev.next =  null ;  
             else  
                 first =  null ;  
             last = last.prev;  
         }  
     }  
       
     /** 
      * 移动到链表头,表示这个节点是最新使用过的 
      * @param node 
      */  
     private  void  moveToHead(CacheNode node) {  
         if  (node == first)  {
             //如果当前节点就是链表的头,不做处理
             return ;  
         }
         if  (node.prev !=  null )  {
             //如果当前节点的前一个元素不为null,把前一个元素的下一个指向当前元素的下一个元素
             node.prev.next = node.next;  
         }
         if  (node.next !=  null )  {
             //如果当前节点的后一个元素不为null,把后一个元素的前一个指向当前元素的前一个元素
             node.next.prev = node.prev;  
         }
         if  (last == node)  {
             //如果当前元素为最后一个元素,则最后一个元素变成当前元素的前一个元素
             last = node.prev;  
         }
         if  (first !=  null ) { 
             //如果第一个算不为null,则当前元素的下一个指向为原来的第一个元素
             //原来的第一个元素的前一个元素变成当前元素
             node.next = first;  
             first.prev = node;  
         }  
         first = node;  
         node.prev =  null ;  
         if  (last ==  null )  {
             last = first;  
         }
     }  
 
}

参考:http://gogole.iteye.com/blog/692103 

http://blog.chinaunix.net/uid-26147414-id-3435752.html 

http://dennis-zane.iteye.com/blog/128278 




     本文转自韩立伟 51CTO博客,原文链接:http://blog.51cto.com/hanchaohan/1538252,如需转载请自行联系原作者





相关文章
|
人工智能 算法 NoSQL
LRU算法的Java实现
LRU(Least Recently Used)算法用于淘汰最近最少使用的数据,常应用于内存管理策略中。在Redis中,通过`maxmemory-policy`配置实现不同淘汰策略,如`allkeys-lru`和`volatile-lru`等,采用采样方式近似LRU以优化性能。Java中可通过`LinkedHashMap`轻松实现LRUCache,利用其`accessOrder`特性和`removeEldestEntry`方法完成缓存淘汰逻辑,代码简洁高效。
676 0
|
缓存 人工智能 算法
lru算法设计与实现
本文详细介绍了LRU(Least Recently Used,最近最少使用)缓存淘汰策略的原理与实现。LRU的核心思想是:越近被访问的数据,未来被再次访问的可能性越大。文章通过Java语言实现了一个支持O(1)时间复杂度操作的LRU缓存
573 0
|
缓存 算法 前端开发
深入理解缓存淘汰策略:LRU和LFU算法的解析与应用
【8月更文挑战第25天】在计算机科学领域,高效管理资源对于提升系统性能至关重要。内存缓存作为一种加速数据读取的有效方法,其管理策略直接影响整体性能。本文重点介绍两种常用的缓存淘汰算法:LRU(最近最少使用)和LFU(最不经常使用)。LRU算法依据数据最近是否被访问来进行淘汰决策;而LFU算法则根据数据的访问频率做出判断。这两种算法各有特点,适用于不同的应用场景。通过深入分析这两种算法的原理、实现方式及适用场景,本文旨在帮助开发者更好地理解缓存管理机制,从而在实际应用中作出更合理的选择,有效提升系统性能和用户体验。
1398 1
|
缓存 监控 算法
如何调整InnoDB的LRU算法以提高效率?
【5月更文挑战第14天】如何调整InnoDB的LRU算法以提高效率?
429 2
|
存储 缓存 算法
面试遇到算法题:实现LRU缓存
V哥的这个实现的关键在于维护一个双向链表,它可以帮助我们快速地访问、更新和删除最近最少使用的节点,同时使用哈希表来提供快速的查找能力。这样,我们就可以在 O(1) 的时间复杂度内完成所有的缓存操作。哈哈干净利索,回答完毕。
379 1
|
缓存 算法 前端开发
前端 JS 经典:LRU 缓存算法
前端 JS 经典:LRU 缓存算法
495 0
|
存储 缓存 算法
LRU(Least Recently Used)算法原理
LRU(Least Recently Used)算法原理
1904 0
|
缓存 算法 Java
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
数据结构~缓存淘汰算法--LRU算法(Java的俩种实现方式,万字解析
|
缓存 算法 前端开发
前端开发者必知的缓存淘汰策略:LRU算法解析与实践
前端开发者必知的缓存淘汰策略:LRU算法解析与实践
1892 0
|
缓存 算法
LRU(Least Recently Used)算法是一种常用的计算机缓存替换算法
【5月更文挑战第4天】LRU算法是基于页面使用频率的缓存策略,优先淘汰最近最久未使用的页面。实现可采用双向链表或数组,前者灵活,后者时间复杂度低。优点是利用时间局部性提高命中率,简单易实现;缺点是占用空间,对循环访问和随机访问场景适应性不佳。
840 0

热门文章

最新文章