当前位置: 首页 > news >正文

用php做购物网站案例个人网页设计作业

用php做购物网站案例,个人网页设计作业,dw网页制作成品下载,长治个人做网站力扣第146题:LRU缓存 一、LRU算法1. 基本概念2. LRU 和 LFU 的区别:3. 为什么 LRU 不需要记录使用频率? 二、Golang代码实现三、代码图解1. LRUCache、DLinkedNode两个结构体2. 初始化结构体对象3. addToHead函数4. removeNode函数5. moveToH…

力扣第146题:LRU缓存

  • 一、LRU算法
    • 1. 基本概念
    • 2. LRU 和 LFU 的区别:
    • 3. 为什么 LRU 不需要记录使用频率?
  • 二、Golang代码实现
  • 三、代码图解
    • 1. LRUCache、DLinkedNode两个结构体
    • 2. 初始化结构体对象
    • 3. addToHead函数
    • 4. removeNode函数
    • 5. moveToHead函数
    • 6. removeTail函数
    • 7. Get函数
    • 8. Put函数

一、LRU算法

1. 基本概念

在 LRU 算法中,首部节点的含义是最近最常访问的节点,而不是使用频率最高的节点。LRU(Least Recently Used) 是一种基于最近使用时间而非使用频率的缓存淘汰算法,核心思想是:最近使用的数据应该优先保留,最近很久未使用的数据应该被淘汰。

2. LRU 和 LFU 的区别:

  • LRU(Least Recently Used):基于数据的使用时间,最近访问的节点会移动到链表头部,而最久未访问的节点会被淘汰。它只关注最后一次访问的时间,不记录具体的访问次数。
  • LFU(Least Frequently Used):基于数据的使用频率,频率最高的节点会优先保留,频率最低的节点会被淘汰。

3. 为什么 LRU 不需要记录使用频率?

在 LRU 算法中,只需要维护每个节点的访问顺序,而不需要记录节点的访问次数。每次访问某个节点时,将该节点移动到链表的头部,而最久未使用的节点则自然在链表尾部。所以要获取最近访问的节点,直接访问链表的头部节点即可。

二、Golang代码实现

type LRUCache struct {size intcapacity intcache map[int]*DLinkedNodehead, tail *DLinkedNode
}type DLinkedNode struct {key, val intprev, next *DLinkedNode
}func initDLinkedNode(key, val int) *DLinkedNode {return &DLinkedNode{key: key,val: val,}
}func Constructor(capacity int) LRUCache {l := LRUCache{cache: map[int]*DLinkedNode{},head: initDLinkedNode(0, 0),tail: initDLinkedNode(0, 0),capacity: capacity,}l.head.next = l.taill.tail.prev = l.headreturn l
}func (this *LRUCache) addToHead(node *DLinkedNode) {node.prev = this.headnode.next = this.head.nextthis.head.next.prev = nodethis.head.next = node
}func (this *LRUCache) removeNode(node *DLinkedNode) {// 将节点从链表中单独抽出来node.prev.next = node.nextnode.next.prev = node.prev
}func (this *LRUCache) moveToHead(node *DLinkedNode) {this.removeNode(node)this.addToHead(node)
}func (this *LRUCache) removeTail() *DLinkedNode {node := this.tail.prevthis.removeNode(node)delete(this.cache, node.key)return node
}// 通过cache的map关系,找到对应的值,该值存储在node的val属性中。
func (this *LRUCache) Get(key int) int {// 如果key是不存在的,那就返回-1if _, ok := this.cache[key]; !ok {return -1}node := this.cache[key]this.moveToHead(node)return node.val
}func (this *LRUCache) Put(key int, val int)  {if _, ok := this.cache[key]; !ok {node := initDLinkedNode(key, val)this.cache[key] = nodethis.addToHead(node)this.size++if this.size > this.capacity {removed := this.removeTail()delete(this.cache, removed.key)this.size--}} else {node := this.cache[key]node.val = valthis.moveToHead(node)}
}

三、代码图解

1. LRUCache、DLinkedNode两个结构体

type LRUCache struct {size intcapacity intcache map[int]*DLinkedNodehead, tail *DLinkedNode
}type DLinkedNode struct {key, val intprev, next *DLinkedNode
}

在这里插入图片描述

map理解为一个存储键值对映射的地方,来(1,1),就存储(1,1),来(2,2),就存储(2,2)。

至于这些(key,val)的顺序,就用链表来控制。为了方便插入、删除节点,所以采用双向链表。

将map和双向链表结合起来,就是将map的val值设置为DoubleNode类型(双向链表类型),DoubleNode里面设置有key,val两个属性(不是映射哦),这里的key和map的key是一样大小的值。

最后的效果就是:通过map的key找到DoubleNode节点,然后找到该节点里面的val属性,至于(key,val)的顺序,是由双向链表去排的,map就是个映射到节点的地方,找到节点,就等于找到val。

2. 初始化结构体对象

func initDLinkedNode(key, value int) *DLinkedNode {return &DLinkedNode{key: key,value: value,}
}func Constructor(capacity int) LRUCache {l := LRUCache{cache: map[int]*DLinkedNode{},head: initDLinkedNode(0, 0),tail: initDLinkedNode(0, 0),capacity: capacity,}l.head.next = l.taill.tail.prev = l.headreturn l
}

在这里插入图片描述

3. addToHead函数

func (this *LRUCache) addToHead(node *DLinkedNode) {node.prev = this.headnode.next = this.head.nextthis.head.next.prev = nodethis.head.next = node
}

请添加图片描述

注意:这里关于节点的顺序,其实是在结构体外去排的,这个节点的顺序并不是排在两个结构体内的哦。

4. removeNode函数

// 将节点从链表中单独抽出来
func (this *LRUCache) removeNode(node *DLinkedNode) {node.prev.next = node.nextnode.next.prev = node.prev
}

请添加图片描述

5. moveToHead函数

func (this *LRUCache) moveToHead(node *DLinkedNode) {this.removeNode(node)this.addToHead(node)
}

把node节点从链表中打断,抽出来,然后将node节点移到this.head后面

6. removeTail函数

func (this *LRUCache) removeTail() *DLinkedNode {node := this.tail.prevthis.removeNode(node)delete(this.cache, node.key)return node
}

请添加图片描述
因为map的key无法直接获得,而node.key和map的key一样,所以用node.key。

7. Get函数

// 通过cache的map关系,找到对应的值,该值存储在node的val属性中。
func (this *LRUCache) Get(key int) int {// 如果key是不存在的,那就返回-1if _, ok := this.cache[key]; !ok {return -1}node := this.cache[key]this.moveToHead(node)return node.val
}

8. Put函数

func (this *LRUCache) Put(key int, val int)  {if _, ok := this.cache[key]; !ok {node := initDLinkedNode(key, val)this.cache[key] = nodethis.addToHead(node)this.size++if this.size > this.capacity {removed := this.removeTail()delete(this.cache, removed.key)this.size--}} else {node := this.cache[key]node.val = valthis.moveToHead(node)}
}

!ok是表示如果map里面的key为空,那就创建一个相应的新节点,让map存储一下key和该节点的映射关系,然后将该节点插入到链表头部,

如果超过LRUCahce的容量,就删除最后一个节点。

如果map里面的key不是空的,那就更新一下map存储的节点,然后将其移动到头部。

http://www.yayakq.cn/news/490711/

相关文章:

  • 摄影赚钱的网站百度极速版
  • 培训班在哪个网站找wordpress 前台发布
  • 站内推广的方法广告牌免费设计在线生成
  • 网站建设资质证书企业年金400退休拿多少
  • 如何申请免费域名做网站怎么找到做外贸的国内公司
  • 做网页专题 应该关注哪些网站潮州移动网站建设
  • 云速网站建设旅行社服务网点能否做网站
  • 宁波方太集团网站建设wordpress 工具栏遮挡
  • centos做网站服务器房屋平面图设计软件app
  • 苏州网站建设排名怎么把做的网站传
  • 营销 网站制作重庆最新宣传片
  • 建设项目竣工验收公告网站做网站编辑需要具备的素质
  • 手机网站菜单栏怎么做深圳网站建设号
  • php怎么写购物网站商品显示页面上海装修公司排名前十强是哪十家
  • 山东济宁省建设厅官方网站微博建网站
  • 学校网站建设发展规划apm安装wordpress网页无法访问
  • 承德手机网站建设重庆网络技术有限公司
  • 网站上360 旋转的图是怎么做的网络管理系统分为哪些层次
  • 服装网站建设平台分析做外贸网站的经验
  • php做网站流程wordpress热门插件
  • 网站上官网标识怎么做网站备案 信息查询
  • 怎样做网站和网站的友情链接杭州定制网站开发
  • 苏州网站设计公司有哪些如何申请网站域名流程
  • 网站栏目页如何做店铺运营方案策划
  • 网站网页建设一般多少钱西地那非副作用太强了
  • 无锡鸿源建设集团有限公司网站网页设计公司有哪些在包头的
  • 内蒙古建设银行网站深圳专业网站设计公司价格
  • 沈阳中小企业网站建设广告网眼布
  • 中小学学校网站建设洛龙区网站制作建设费用
  • 二道网站建设福田祥菱官网