简单实现LRU算法(Least Recently Used最近最少使用)

LRU即Least Recently Used的缩写,即最近最少使用,可以用来作为路由或者淘汰算法。

算法的思想是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。正是由于这个特性,所以我们可以将使用不到的数据淘汰。

基于链表的 LRU 实现 [头部是最新的数据(访问或者插入)]
思路:每次新插入数据的时候将新数据插到链表的头部;每次缓存命中(即数据被访问),则将数据移到链表头部;那么当链表满的时候,就将链表尾部的数据淘汰。

主要构成有get和put两个方法
get时将访问的数据放到头部(访问)
put时有两种情况
1.未达到最大容量,直接头部插入数据(插入)。
2.达到最大容量,则将末尾数据删除(淘汰最少使用),然后在头部插入数据(插入)。

public class LRUSimple {
	
	private int cap = 0;
	private LinkedList<User> link = new LinkedList<>(); 
	LRUSimple(int capcity){
		this.cap=capcity;
	}
	public User get(String user){
		User u = null;
		for(User tmp:link){
			u=tmp;
			if(tmp.getUser()==user){
			//-------将数据移到头部----------
				link.remove(tmp);
				link.addFirst(tmp);
			//------------------------------
			}
		}
		return u;
	}
	
	public void put(User u){
		if(link.size()==cap){//如果达到容量则将末尾数据删除(淘汰最少使用)
			link.removeLast();
		}
		link.addFirst(u);//头部插入数据
	}
	
	public static void main(String[] args) {
		// 测试
		LRUSimple lru = new LRUSimple(3);
		lru.put(new User("hzc","5"));
		lru.put(new User("hc","5"));
		lru.put(new User("h","5"));
		lru.get("hzc");
		lru.put(new User("h2c","5"));
		System.out.println(lru.toString());
	}
	
	
	@Override
	public String toString() {
		return link.toString();
	}

//---------------------实体类----------------------------
	static class User{
		private String user;
		private String age;
		
		
		public User(String user, String age) {
			super();
			this.user = user;
			this.age = age;
		}
		public String getUser() {
			return user;
		}
		public void setUser(String user) {
			this.user = user;
		}
		public String getAge() {
			return age;
		}
		public void setAge(String age) {
			this.age = age;
		}
		@Override
		public String toString() {
			return "User [user=" + user + ", age=" + age + "]";
		}
		
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LRU (Least Recently Used) 是一种常见的页面置换算法,在操作系统中被广泛使用。它的核心思想是,如果一个页面最近一段时间内没有被访问,那么它很可能在未来也不会被访问,因此可以将其替换出内存,腾出空间给其他页面使用。 下面是使用C++模拟LRU算法的示例代码: ```c++ #include <iostream> #include <list> #include <unordered_map> using namespace std; class LRUCache { public: LRUCache(int capacity) : capacity(capacity) {} int get(int key) { auto it = cache.find(key); if (it == cache.end()) { // 如果key不存在 return -1; } // 将节点移动到链表头部,并返回value cache_list.splice(cache_list.begin(), cache_list, it->second); return it->second->second; } void put(int key, int value) { auto it = cache.find(key); if (it != cache.end()) { // 如果key已经存在,更新value并将节点移动到链表头部 it->second->second = value; cache_list.splice(cache_list.begin(), cache_list, it->second); return; } if (cache.size() == capacity) { // 如果cache已满,删除链表尾部节点 auto last = cache_list.back(); cache.erase(last.first); cache_list.pop_back(); } // 在链表头部插入新节点 cache_list.emplace_front(key, value); cache[key] = cache_list.begin(); } private: int capacity; list<pair<int, int>> cache_list; // 使用双向链表保存key-value对 unordered_map<int, list<pair<int, int>>::iterator> cache; // 使用哈希表快速查找key对应的节点 }; int main() { LRUCache cache(2); cache.put(1, 1); cache.put(2, 2); cout << cache.get(1) << endl; // 返回 1 cache.put(3, 3); // 该操作会使得 key 2 作废 cout << cache.get(2) << endl; // 返回 -1 cache.put(4, 4); // 该操作会使得 key 1 作废 cout << cache.get(1) << endl; // 返回 -1 cout << cache.get(3) << endl; // 返回 3 cout << cache.get(4) << endl; // 返回 4 return 0; } ``` 在上面的代码中,我们使用了双向链表和哈希表来维护LRU缓存。其中,双向链表用于按照访问时间排序缓存中的节点,哈希表则用于快速查找某个key对应的节点在链表中的位置。当有新的key-value对要插入缓存时,如果缓存已满,则删除链表尾部的节点;如果key已经存在,则更新value并将对应的节点移动到链表头部;否则,在链表头部插入新节点。当需要从缓存中获取某个key对应的value值时,我们在哈希表中查找key对应的节点,将其移动到链表头部,并返回value。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值