温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

JavaScript怎么实现LRU缓存淘汰算法

发布时间:2023-04-26 11:25:54 来源:亿速云 阅读:118 作者:iii 栏目:开发技术

这篇文章主要讲解了“JavaScript怎么实现LRU缓存淘汰算法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript怎么实现LRU缓存淘汰算法”吧!

如何实现LRU缓存淘汰算法?

LRU(Least Recently Used)缓存淘汰算法是一种常见的缓存淘汰策略,它的核心思想是优先淘汰最近最少使用的缓存数据,以保证缓存中的数据始终是最热门的。

使用哈希表和双向链表

LRU缓存淘汰算法的核心在于如何快速定位最近最少使用的缓存数据,这可以通过哈希表和双向链表的结合来实现。具体来说,我们可以使用一个哈希表来存储缓存数据的键值对,同时使用一个双向链表来维护缓存数据的访问顺序,每次访问缓存时,我们将访问的数据节点移动到链表头,当缓存满时,淘汰链表尾部的节点即可。

哈希表实现LRU缓存淘汰算法

下面是一个使用哈希表实现LRU缓存淘汰算法的例子,假设我们要实现一个最大容量为3的缓存:

import java.util.HashMap;
import java.util.Map;

class LRUCache<K, V> {
    private int capacity;
    private Map<K, Node<K,V>> cache;
    private Node<K,V> head;
    private Node<K,V> tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node<>(null, null);
        this.tail = new Node<>(null, null);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }

    public V get(K key) {
        if (!cache.containsKey(key)) {
            return null;
        }
        Node<K,V> node = cache.get(key);
        remove(node);
        addFirst(node);
        return node.value;
    }

    public void put(K key, V value) {
        if (cache.containsKey(key)) {
            Node<K,V> node = cache.get(key);
            node.value = value;
            remove(node);
            addFirst(node);
        } else {
            if (cache.size() == capacity) {
                Node<K,V> node = removeLast();
                cache.remove(node.key);
            }
            Node<K,V> node = new Node<>(key, value);
            cache.put(key, node);
            addFirst(node);
        }
    }

    private void remove(Node<K,V> node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void addFirst(Node<K,V> node) {
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    private Node<K,V> removeLast() {
        Node<K,V> node = tail.prev;
        remove(node);
        return node;
    }

    private static class Node<K, V> {
        K key;
        V value;
        Node<K,V> prev;
        Node<K,V> next;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
}

在这个例子中,我们使用了一个哈希表cache来存储缓存数据的键值对,同时使用了一个双向链表来维护缓存数据的访问顺序,其中headtail分别表示链表头和链表尾,每次访问缓存时,我们将访问的数据节点移动到链表头,当缓存满时,淘汰链表尾部的节点即可。

注意,为了方便起见,我们在链表头和链表尾分别添加了一个哨兵节点headtail,这样就不需要在代码中处理链表为空的情况了。

下面是一个使用双向链表实现LRU缓存淘汰算法的例子,假设我们要实现一个最大容量为3的缓存:

import java.util.HashMap;
import java.util.Map;

class LRUCache<K, V> {
    private int capacity;
    private Map<K, Node<K,V>> cache;
    private Node<K,V> head;
    private Node<K,V> tail;

    public LRUCache(int capacity) {
        this.capacity = capacity;
        this.cache = new HashMap<>();
        this.head = new Node<>(null, null);
        this.tail = new Node<>(null, null);
        this.head.next = this.tail;
        this.tail.prev = this.head;
    }

    public V get(K key) {
        if (!cache.containsKey(key)) {
            return null;
        }
        Node<K,V> node = cache.get(key);
        remove(node);
        addFirst(node);
        return node.value;
    }

    public void put(K key, V value) {
        if (cache.containsKey(key)) {
            Node<K,V> node = cache.get(key);
            node.value = value;
            remove(node);
            addFirst(node);
        } else {
            if (cache.size() == capacity) {
                Node<K,V> node = removeLast();
                cache.remove(node.key);
            }
            Node<K,V> node = new Node<>(key, value);
            cache.put(key, node);
            addFirst(node);
        }
    }

    private void remove(Node<K,V> node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void addFirst(Node<K,V> node) {
        node.next = head.next;
        node.prev = head;
        head.next.prev = node;
        head.next = node;
    }

    private Node<K,V> removeLast() {
        Node<K,V> node = tail.prev;
        remove(node);
        return node;
    }

    private static class Node<K, V> {
        K key;
        V value;
        Node<K,V> prev;
        Node<K,V> next;

        public Node(K key, V value) {
            this.key = key;
            this.value = value;
        }
    }
}

在这个例子中,我们使用了一个哈希表cache来存储缓存数据的键值对,同时使用了一个双向链表来维护缓存数据的访问顺序,其中headtail分别表示链表头和链表尾,每次访问缓存时,我们将访问的数据节点移动到链表头,当缓存满时,淘汰链表尾部的节点即可。

注意,为了方便起见,我们在链表头和链表尾分别添加了一个哨兵节点headtail,这样就不需要在代码中处理链表为空的情况了。

感谢各位的阅读,以上就是“JavaScript怎么实现LRU缓存淘汰算法”的内容了,经过本文的学习后,相信大家对JavaScript怎么实现LRU缓存淘汰算法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是亿速云,小编将为大家推送更多相关知识点的文章,欢迎关注!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI