栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

JAVA有序表(双向链表)实现LRU缓存算法,用哈希表(HashMap)降低时间复杂度

Java 更新时间:发布时间: 百科书网 趣学号
JAVA实现LRU缓存算法,用哈希表(HashMap)降低时间复杂度 1、算法分析

上一篇我们用链表简单的实现了LRU的算法思维以及算法,我们最后分析的时间复杂度为0(n),n为链表中的长度,我们用的是单链表,单链表实现的,所有删除需要查找到对应的节点,利用哨兵的思维,监控查找的前一个节点。就能轻松实现删除。上一篇的LRU分析和简单实现

1.1利用哈希表降低时间复杂度(链表是双向链表)

有没有更好的办法来降低时间的复杂度呢?答案是利用哈希表,哈希表的key就是链表中的data,哈希表的value,存储的是每一个节点node。我们在查找和删除的时候,只需要在HashMap中找到node,然后从链表中删除node,而我们利用哈希表删除,查找,添加的时间复杂度接近O(1),

1.2 示意图

2、代码的实现
import java.util.HashMap;
import java.util.Map;

public class Chain {
	public class Node{
		public int data;
		public Node next;
		public Node pre;
	}
	
	private Map map=new HashMap();
	
	private Node head=null;
	
	private Node tail=null;
	
	public void LUR(int data) {
		
		if(map.containsKey(data)) {
			Node node=map.get(data);
			
			 if(node.data==tail.data) {
				//tail=tail.pre;
				//tail.next=null;
				 delNode(data);
				 
				node.next=head;
				head.pre=node;
				head=node;
			}
			 
			if(node.data!=head.data) {		
				node.next.pre=node.pre;
				node.pre.next=node.next;
				node.next=head;
				node.pre=node;
				head=node;//头指针永远指向头
			}		
		}
		
		else {
			
			if(head==null) {
				addNode(data);	
			}
			else {
				
				Node node=new Node();
				node.data=data;
				node.next=head;
				head.pre=node;
				head=node;
				map.put(data, node);
			}
		}
	}
	
	public void delNode(int data) {
		Node node=map.get(data);
		map.remove(data);//把值从map中删除
		if(node.data==head.data) {
			
			head=head.next;
			head.pre=null;//头节点的下一个节点赋值给头节点。此时的头节点的pre是有值的,所以需要置为null;	
		}
		else if(node.data==tail.data) {
			tail=tail.pre;
			tail.next=null;	
		}
		else {
			
			node.next.pre=node.pre;
			
			node.pre.next=node.next;
		}	
	}
	
	public void addNode(int data) {
		Node node=new Node();
		node.data=data;
		map.put(data, node);
		if(head==null) {
			head=node;
			tail=node;
		}
		else {
			node.pre=tail;
			tail.next=node;
			tail=node;	
		}	
	}
	
	public boolean searchNode(int data) {
		return map.containsKey(data);
	}
	
	
	
	public void testMap(int data) {
		Node node=map.get(data);
		System.out.println("******************test:"+node.pre.data);
	}
	
	
	public void printlNode() {
		
		Node target=head;
		while(target!=null) {
			System.out.println(target.data);
			target=target.next;
		}
		
	}
}

3、在main方法中测试
public class testMain {
	public static void main(String[] args) {
		Chain chain=new Chain();
		chain.addNode(1);
		chain.addNode(2);
		chain.addNode(3);
		chain.addNode(4);
		chain.addNode(5);
		
		chain.LUR(5);
		chain.LUR(6);
		chain.LUR(6);
		chain.LUR(7);
		chain.LUR(7);
		
		
		
		chain.delNode(7);
		
	//System.out.println(chain.searchNode(6));
		
		//chain.testMap(2);
		chain.printlNode();
	}

}

4、测试结果

5、结尾提示

本次代码没有完成一个小小的功能,缓存系统的大小。如果有需要可以自己实现,需要引入一个哨兵来监控缓存系统的剩余容量,如果满则删除链表的尾节点,只需要挪动哨兵tail指针即可删除。

转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/281553.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号