LRU算法 swift版本

//
//  LRUCache.swift
//  LRUCache
//
//  Created by wangjin on 2021/10/27.
//


//LRU( Least Recently Used 最近使用过数据)

//目的:计算机的缓存容量有限,如果缓存满了就要删除一些内容,给新内容腾位置,解决删除哪些数据的算法
//算法核心:双向链表和哈希表的结合体。是让时间复杂度为 O(1)
//工作流程:缓存淘汰策略
//大体思想:
//1.设置一个最大容量 capacity
//2.实现两个接口 一个是 put(key,val)方法 存入键值 一个是get(key) 方法取出对应val
//3.cache 中查找键是否已存在;如果容量满了要删除最后一个数据;每次访问还要把数据插入到队头。


///代码 步骤:
///1.创建一个双链表节点
 class Node {
    /// 存时候的key string类型
     var key : String?
    /// 存的值 任意值
     var val : Any?
    /// 下一个节点
     var next : Node?
    /// 上一个节点
     var prev : Node?
    
    /// 节点初始化 传入 key 和val
    init(key:String?,val:Any?) {
        self.key = key
        self.val = val
    }
}

/// 创建一个双链表
 class DoubleList {
    /// 头尾虚节点
    /// 头节点
    var head : Node?
    /// 尾节点
    var tail : Node?
    /// 链表长度
    var size : Int = 0
    
    init() {
        head = Node(key: nil, val: nil)
        tail = Node(key: nil, val: nil)
        size = 0
        
        /// 头指尾 尾指头 循环起来
        head?.next = tail
        tail?.next = head
        
    }
    
    /// 链表头部添加节点 node
    func addFirst(node:Node) {
        
        /// 这个得自己画图
        /// 当前节点下一个 指向 头节点下一个
        /// 当前节点上一个 指向头节点
        /// 头节点下一个节点的上一个节点 指向当前节点
        /// 头节点下一个节点 指向当前节点

        node.next = head?.next
        node.prev = head
        head?.next?.prev = node
        head?.next = node
        /// 元素数加1
        size += 1
        
    }
    
    /// 删除链表中某个节点 node 必须有节点
    func removeNode(node:Node){
        ///这个自己画
        node.prev?.next = node.next
        node.next?.prev = node.prev
        /// 元素减1
        size -= 1
        
    }
    
    /// 删除最后一个节点 并返回该节点
    func removeLast() -> Node? {
        if size == 0 {
            return nil
        }
        let last = tail?.prev
        removeNode(node:last!)
        return last
    }
    
}



public class LRUCache {
    
    /// 哈希map
   private var map : [String? : Node?]
    /// 双向链表
   private var doubleList : DoubleList
    /// 最大容量 传入
   private var capacity : Int
    
    init(capacity : Int) {
        self.capacity = capacity
        self.map = [:]
        self.doubleList = DoubleList.init()
    }
    
    
   public func get(key : String) -> Any? {

        if map[key] == nil {
            return nil
        }
        
        let val = (map[key] as? Node)?.val
        //这里是为了把数据提前
        put(key: key, val: val)
        return val
    }
    
  public  func put(key:String,val:Any?) {
        
        let node = Node.init(key: key, val: val)
        if map[key] != nil {
            //删除旧节点
            doubleList.removeNode(node: (map[key] as? Node)!)
            //插入新节点
            doubleList.addFirst(node: node)
            //更新map数据
            map[key] = node
        }else {
            
            if capacity == doubleList.size {
                //删除最后一个节点
                guard let last = doubleList.removeLast() else {
                    return
                }
                map.removeValue(forKey: last.key)
            }
            // 添加到头部
            doubleList.addFirst(node: node)
            //更新map
            map[key] = node
        }
    }
    
}

下面是调用

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let cache = LRUCache.init(capacity: 2)
        cache.put(key: "1", val: 1)
        cache.put(key: "2", val: 2)
        let val = cache.get(key: "1")
        print(val)
        cache.put(key: "3", val: 3)
       let val2 = cache.get(key: "2")
        print(val2)
        
    }


}

结果


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,386评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,142评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,704评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,702评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,716评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,573评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,314评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,230评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,680评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,873评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,991评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,706评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,329评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,910评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,038评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,158评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,941评论 2 355

推荐阅读更多精彩内容