1. 程式人生 > 實用技巧 >基於雙向連結串列實現的LRU演算法,支援泛型

基於雙向連結串列實現的LRU演算法,支援泛型

先一篇泛型總結得很好的部落格:https://segmentfault.com/a/1190000014120746

用雙向連結串列實現LRU,要求可以指定快取大小,並且可以儲存任意型別的資料。
(要求用泛型,只需要實現新增方法即可)
分析:
1.LRU實現
操作:
新增:是否存在?存在-刪除-新增到表頭; 不存在-看錶長?刪除末尾新增到表頭 or 直接新增到表頭
刪除:查詢,存在-刪除
資料結構:帶表頭雙鏈表

2.任意型別資料-泛型實現

 1 package day3practice;
 2 
 3 
 4 public class GenericParadigm {
 5     public
static void main(String args[]){ 6 ListLRUGenne<Integer> lru = new ListLRUGenne<>(6,new NodeGenne()); 7 lru.addNodeLRU(5); 8 lru.addNodeLRU(4); 9 lru.addNodeLRU(3); 10 lru.addNodeLRU(2); 11 lru.addNodeLRU(1); 12 lru.printLRU();
13 lru.addNodeLRU(6); 14 lru.printLRU(); 15 lru.addNodeLRU(3); 16 lru.printLRU(); 17 lru.addNodeLRU(7); 18 lru.printLRU(); 19 // 20 ListLRUGenne<String> lru2 = new ListLRUGenne<>(6,new NodeGenne()); 21 lru2.addNodeLRU("一護");
22 lru2.addNodeLRU("鳴人"); 23 lru2.addNodeLRU("路飛"); 24 lru2.addNodeLRU("奇伢"); 25 lru2.addNodeLRU("愛德華"); 26 lru2.printLRU(); 27 lru2.addNodeLRU("兵長"); 28 lru2.printLRU(); 29 lru2.addNodeLRU("奇伢"); 30 lru2.printLRU(); 31 lru2.addNodeLRU("柯南"); 32 lru2.printLRU(); 33 34 35 } 36 }
 1 package day3practice;
 2 
 3 
 4 public class ListLRUGenne<T> { //帶頭結點的單鏈表,根據題意,所有結點值不同
 5     static int lenLimit;
 6     static NodeGenne headNode = new NodeGenne();
 7     public ListLRUGenne(int lenLimit,NodeGenne headNode){
 8         this.lenLimit = lenLimit;
 9         this.headNode = headNode;
10     }
11 
12     static public int length(){
13         int length = 0;
14         NodeGenne scan = headNode;
15         while(scan.next!=null){
16             scan=scan.next;
17             length++;
18 
19         }
20         return  length;
21     }
22 
23     //LRU演算法的新增的邏輯:
24     public void addNodeLRU(T value){
25         NodeGenne newone = new NodeGenne(value);//先建立一個待加入的新結點
26         NodeGenne p = headNode;//p是掃描指標
27 
28         while(p.value != newone.value&&p.next!=null){
29             p=p.next;
30         }
31         //出迴圈兩種可能,遍歷結束沒有找到,或者是找到了
32         if(p.next == null){//遍歷完了沒有找到
33             int len= ListLRUGenne.length();
34             if(len<lenLimit){ //不需要刪除操作,直接在頭部新增
35                addNode(headNode,newone);
36 
37             }else{
38                 //先刪除最後一個結點
39                 deleteNode(p);
40                 //再在列表頭部新增
41                 addNode(headNode,newone);
42 
43             }
44         }else{ //找到了這個結點,刪除,在頭部新增
45             deleteNode(p);
46             addNode(headNode,newone);
47         }
48     }
49 
50     public void deleteNode(NodeGenne p){
51         if(p.next == null){
52             p.pre.next = null; //刪除的是尾結點
53         }
54         else{//刪除的是中間結點
55             p.pre.next = p.next;
56             p.next.pre = p.pre;
57         }
58     }
59 
60 //雙鏈表新增結點
61     public void addNode(NodeGenne p,NodeGenne newone){
62         if(p.next == null){ //末尾新增
63             p.next = newone;
64             newone.pre = p;
65         }else{ // 中間新增
66             newone.next = p.next;
67             newone.pre = p;
68             p.next.pre = newone;
69             p.next = newone;
70         }
71 
72     }
73 
74     public void printLRU(){
75         NodeGenne p = headNode;
76         if(p.next == null) System.out.println("LRU連結串列當前無結點");
77         while(p.next!= null){
78             p = p.next;
79             System.out.print(p.value+"  ");
80         }
81         System.out.println();
82     }
83 }
 1 package day3practice;
 2 
 3 public class NodeGenne <T>{
 4     T value;
 5     NodeGenne next=null;
 6     NodeGenne pre = null;
 7 
 8     public NodeGenne(T value, NodeGenne next,NodeGenne pre){
 9         this.value = value;
10         this.next = next;
11         this.pre = pre;
12     }
13     public NodeGenne(T value){
14         this.value = value;
15     }
16     public NodeGenne(){
17     }
18 
19 }

//用雙向連結串列實現LRU,要求可以指定快取大小,並且可以儲存任意型別的資料。
// (要求用泛型,只需要實現新增方法即可)
//分析:
/*1.LRU實現
操作:
新增:是否存在?存在-刪除-新增到表頭; 不存在-看錶長?刪除末尾新增到表頭 or 直接新增到表頭
刪除:查詢,存在-刪除
資料結構:帶表頭雙鏈表

2.任意型別資料-泛型實現
*/