LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。

为什么要使用链表实现呢,因为这个页面不会很多,内存和资源开销都小

在计算机中,开销往往是需要考虑的,我们不希望占用过多的系统资源,动态路由小型网络使用RIP(Bellman-Ford Routing Algorithm),大型网络设备用的就是OSPF(dijkstra),当然也有很多方面的考虑,比如RIP配置和管理更简单,RIP为了避免出现网络延迟太高,也将路由器最大的允许跳数设为15

我们存储的时候就按照时间吧,末尾为刚刚使用的,淘汰前面的

然后我们来考虑下这个算法,保证我们不使用无关变量。这个cache是空的

进行一次请求需要查看我当前的cache里是否存在这个数据

1存在

存在就比较简单了,直接取出数据,页面数据不变,并把这个结点放在最后

2不存在

2.1cache满

把最靠前的页面用读取数据的数据覆盖,然后把它放到最后的cache

2.2cache不满

直接去读取数据,然后把他放在最后的页面

我需要维护的是一个编号(或者说地址)还有后结点,然后查询肯定是O(1)的,这是内部完成的,不需要我考虑(直接得到地址去取数据)

缺页中断都对应了一个硬件操作,就是去取这个数据

#include #includestructnode

{intid;struct node *next;

}* head, *tail, *p;voidPushBack()

{/*pre没有意义,仅需要多保留一个尾结点

p->pre = tail; //使pre指向前一个节点,循环可得到反向链表*/p->next =NULL;

tail->next =p;

tail=p;

}voidfun()

{struct node *q;

q=head;while (q->next !=NULL)

{if (q->next->id == p->id)//不缺页

{

PushBack();

p= q->next;

q->next = p->next;free(p);return; //执行完全部操作停掉

}

q= q->next;

}

printf("发生缺页中断 %d\n",p->id);

PushBack();

p= head->next;

head->next = p->next;free(p);

}intmain()

{intsum, n, i;

sum= 0; //初始cache内没有数据

scanf("%d", &n); //读入页数

head = (struct node *)malloc(sizeof(structnode));

head->next =NULL;

tail=head;while (1)

{

p= (struct node *)malloc(sizeof(structnode));

scanf("%d", &p->id);if (p->id < 0)

{break;

}else{if (sum < n) //cache未满,放至后面

{

PushBack();

printf("发生缺页中断 %d\n",p->id);

sum+= 1; //并对cache+1

}else{

fun();

}

}

}return 0;

}

事后来看,我说pre没有意义是不对的,因为实际上并不是乱序的,往往我们先访问的到的会被继续访问,并不是一个完全的均摊复杂度。

所以应该记录pre进行倒序,有兴趣的可以实现一下,不过我还是觉得c++好写,但是内部肯定是更厉害的

c++实现就用list搞一下啊,把最近访问的放到最前面

#include#includevoid fun(std::list&L,intx)

{for(std::list::iterator it=L.begin();it!=L.end();it++)

{if(*it==x)

{

L.push_front(x);

L.erase(it);return;

}

}

std::cout<

L.pop_back();

L.push_front(x);

}

intmain()

{

std::listL;intsum, n, i,x;

sum= 0; //初始cache内没有数据

std::cin>>n; //读入页数

while (true)

{

scanf("%d", &x);if (x < 0)

{break;

}else{if (sum < n) //cache未满,放至后面

{

L.push_front(x);

std::cout<

sum += 1; //并对cache+1

}else{

fun(L,x);

}

}

}return 0;

}

C++ list 因为内部就是双向链表

public classLRUCache{private intlimit;private HashMaphashMap;privateNode head;privateNode end;public LRUCache(intlimit)

{this.limit =limit;

hashMap= new HashMap();

}publicString get(String key){

Node node=hashMap.get(key);if(node ==null)return null;

refreshNode(node);returnnode.value;

}public voidput(String key,String value){

Node node=hashMap.get(key);if(node == null){if(hashMap.size()>=limit)

{

String oldKey=removeNode(head);

hashMap.remove(oldKey);

}

node= newNode(key,value);

addNode(node);

hashMap.put(key,node)

}else{

node.value=value;

refreshNode(node);

}

}public voidremove(String key){

Node node=hashMap.get(key);

removeNode(node);

hashMap.remove(key);

}private voidrefreshNode(Node node)

{if(node ==end)return;

removeNode(node);

addNode(node);

}publicString removeNode(Node node){if(node ==end)

end=end.pre;else if(node ==head)

head=head.next;else{

node.pre.next=node.next;

node.next.pre=node.pre;

}returnnode.key;

}public voidaddNode(Node node)

{if(end!=null)

{

end.next=node;

node.pre=end;

node.next= null;

}

end=node;if(head == null)

head=node;

}

}

Java实现(高并发线程安全使用ConcurrentHashMap

lru算法c语言实现单链表,操作系统之LRU算法 C语言链表实现相关推荐

  1. 操作系统学习之用C语言模拟LRU算法

    前言 LRU算比较经典,而且考的也比较多,LRU算法全称Least Recently Used,译为最近最少使用.用C模拟一下吧. Buddy算法:操作系统学习之用C语言模拟伙伴(Buddy)算法 F ...

  2. TypeScript算法专题 - blog1.基于TypeScript语言的单链表实现

    TypeScript算法专题 - 基于TypeScript语言的单链表实现 李俊才 CSDN:jcLee95 邮箱:291148484@163.com 专题目录:https://blog.csdn.n ...

  3. Go语言-实现单链表反转算法

    Go语言实现链表的逆序_头插法 头插法与尾插法 头插法 概念 特点 核心过程 Go语言实现 ==注意==:上述方法是带头指针的头插法的实现,如果是带头节点的头插法需要做一定的修改 如果是带头节点的,则 ...

  4. C语言实现单链表逆置算法

    题目: 设计算法,将单链表L就地逆置,结果如图所示: 代码: #include<stdio.h> #include<stdlib.h> typedef int dataType ...

  5. 【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

    一.线性表 1.1 概念与特点 1.2 线性表的存储结构 1.3 常见操作 1.4 应用场景 二.链表 2.1 链表简介 2.2 单向链表(单链表) 2.21 基本概念 2.22 单链表基本操作 2. ...

  6. 操作系统学习之用C语言模拟伙伴(Buddy)算法

    前言 学到了操作系统的的虚拟内存部分,硬件不太好的我学起来有些吃力,概念性知识点太多,所以我决定用软件的方式,实现一下虚拟内存常用的算法,因为用到了指针,暂时用C语言写一下Buddy算法.FIFO算法 ...

  7. 看动画理解「链表」实现LRU缓存淘汰算法

    前几节学习了「链表」.「时间与空间复杂度」的概念,本节将结合「循环链表」.「双向链表」与 「用空间换时间的设计思想」来设计一个很有意思的缓存淘汰策略:LRU缓存淘汰算法. 循环链表的概念 如上图所示: ...

  8. 操作系统学习之用C语言模拟FIFO算法

    前言 FIFO算法比较简单,没什么好说的,就是先进先出.不过我添加了3状态,不过也只有堵塞,没有将阻塞进程唤醒的过程. Buddy算法:操作系统学习之用C语言模拟伙伴(Buddy)算法 FIFO算法: ...

  9. 用c语言实现单链表的初始化,建表,查找,求长度,插入,删除等操作,【YTU+2430+C语言习题+链表建立+插入+删除+输(5)...

    的打印.判断链表是否为空.计算链表长度.插入节点.删除节点.删除整个链表.(2) 线性表adt顺序存储实现中的创建.查找.插入和删除等基本操作及相关算法,线性表adt链式存储实现中单链表.循环链表和双 ...

最新文章

  1. 计算机开不开机是什么原因是什么原因,电脑开不了机的原因,详细教您电脑开不了机怎么办...
  2. 【树链剖分】Milk Visits G(luogu 5838)
  3. java全局异常处理_详解Spring全局异常处理的三种方式
  4. 前端学习(2672):ts初步概念和功能实现
  5. 【HNOI2013】数列
  6. colorkey唇釉是否安全_Colorkey 空气唇釉真的那么好用吗?
  7. eclipse代码加版权头插件
  8. 2018年中国互联网企业百强榜单揭晓
  9. 二.公共建筑安全防范系统配置
  10. [推荐]一款非常方便好用的输入法--拼音加加
  11. cropper.js使用
  12. SQL语句:联合查询
  13. 纸牌游戏--小猫钓鱼
  14. 如何看linux网络慢,Linux下网速慢的问题
  15. 荒野、车居生活与自由世界——读《车轮上的瓦尔登湖》
  16. day03 数据预处理
  17. 日置(HIOKI)MR8875-30数据处理
  18. 云和恩墨做的是oracle,云和恩墨张中靖:立足Oracle技术,顺应去IOE大势 原创
  19. 1核2G3M,系统盘40G,流量500G/月,83一年
  20. 计算机基础课程听课记录,听课记录-计算机应用基础

热门文章

  1. pipeline(管道的连续应用)
  2. 错误记录:发送广播是报空指针
  3. asp.net repeater控件
  4. 使用WCF实现消息推送
  5. 使用 Hasor 从数据库查询显示到页面上
  6. Android系统搜索对话框(浮动搜索框)的使用
  7. 基本数据类型和包装数据类型的使用标准
  8. 列出搜索过的数据(类似京东顶部搜索框)
  9. 洛谷 P1048 采药 01背包入门
  10. 对于react-redux的理解