LRU缓存实现

来源:互联网 发布:人工智能能超越人脑么 编辑:程序博客网 时间:2024/06/05 16:46

本着自己实操的原则..手撸了一遍算法4上一道LRU缓存的题,没用java自带的那坨东西,手写了一遍LRU要用到Hash散列表,双向队列,然而并没有看很懂书上写的用符号表存链表元素位置是干啥的。。这坨代码我自己都不想看了,太丑了。

/** * Created by eminem on 16-11-29. * <p> * Created by eminem on 16-11-29. * 双向链表 * isEmpty()判断是否为空 * size() 元素数量 * void pushleft() pushRight() 从左右添加元素 * Item popLeft popRight() 从左右删除元素 * show() 打印元素 **/public class LRU<Item> {    /**     * 0.0     **/    LRU.queue fuck;    LRU.sanlie shit;    private class Node {        Item item;        Node front;        Node next;    }    private Node first;    private Node last;    //双向队列里的    private int N=0;    //散列表的链表数量    private int M = 997;    private iSequentialSearchST<String, Integer>[] st;    /**     * LRU构造器     **/    public LRU() {        st = (iSequentialSearchST<String, Integer>[]) new iSequentialSearchST[M];        for (int i = 0; i < M; i++) {            st[i] = new iSequentialSearchST();        }        /**         * fuck:queue         * shit:sanlie         **/        fuck = this.new queue();        shit = this.new sanlie();    }    /**     * 队列     **/    class queue {        private Node first;        private Node last;        public boolean isEmpty() {            return N == 0;        }        //当next为null时不知道null.item是不是会出错        public Item delete(Item item) {            Node x = first;            if (item.equals(x.item)) {                return x.item;            }            Item it;            for (; x != null; x = x.next) {                if (item.equals(x.item)) {                    it = x.item;                    if (x.next == null) {                        x.front.next = null;                        fuck.pushLeft(item);                        N--;                        return it;                    }                    x.front.next = x.next;                    x.next.front = x.front;                    fuck.pushLeft(item);                    N--;                    return it;                }            }            return null;        }        public int size() {            return N;        }        public void pushLeft(Item item) {            Node oldfirst = first;            first = new Node();            first.item = item;            if (isEmpty()) {                last = first;                first.next = null;            } else {                oldfirst.front = first;                first.next = oldfirst;            }            N++;        }        public void pushRight(Item item) {            Node oldlast = last;            last = new Node();            last.next = null;            last.item = item;            if (isEmpty()) {                first = last;                last.front = null;            } else {                last.front = oldlast;                oldlast.next = last;            }            N++;        }        public Item popLeft() {            if (isEmpty()) {                last = null;                first = null;                return null;            }            Item item = first.item;            first = first.next;            //假设弹出操作之后链表里还有元素,那么把first的front设置为null            //如果没有元素了,那么正好,这几行代码也不用执行了,全都等于null了            if (first != null) {                first.front = null;            }            N--;            return item;        }        public Item popRight() {            if (isEmpty()) {                first = null;                last = null;                return null;            }            Item item = last.item;            last = last.front;            if (last != null) {                last.next = null;            }            N--;            return item;        }        public void show() {            for (Node x = first; x != null; System.out.println(x.item), x = x.next) ;        }    }    /**队列**/    /**     * 散列表     **/    class sanlie {        private int hash(String key) {            return (key.hashCode() & 0x7fffffff) % M;        }        private Integer get(String key) {            return st[hash(key)].get(key);        }        private void put(String key, Integer val) {            st[hash(key)].put(key, val);        }        private Integer delete(String key) {            return st[hash(key)].delete(key);        }        private boolean contains(String key) {            int fuck = hash(key);            return st[fuck].contains(key);        }    }    /**散列表**/    /**LRU的方法**/    /**     * 访问方法     * 当调用visit方法时,首先检查散列表有没有该元素,     * <p>     * A:若[有]该元素,     * 1.把他从链表删除并插入到链表开头,     * 2.改变他在散列表中的内容     * <p>     * B:若[没有]该元素,     * 1.把该元素直接插入到链表开头     * 2.在散列表中加入该元素,并把他的位置写为最新的那个位置     **/    public void visit(String key) {        boolean judge = shit.contains(key);        //B:        if (!judge) {            fuck.pushLeft(key);            shit.put(key, 0);        } else if (judge) {            fuck.delete(key);        }    }    public Item delete() {        return (Item) fuck.popRight();    }    /**LRU的方法**/}class iSequentialSearchST<String, Integer> {    private Node first;    private class Node {        String Key;        Integer val;        Node next;        public Node(String key, Integer val, Node next) {            this.Key = key;            this.val = val;            this.next = next;        }    }    protected boolean contains(String key) {        for (Node x = first; x != null; x = x.next) {            if (key.equals(x.Key)) {                return true;            }        }        return false;    }    protected Integer get(String key) {        for (Node x = first; x != null; x = x.next) {            if (key.equals(x.Key)) {                return x.val;            }        }        System.out.println("get:Can't find the key" + "=" + "\"" + key + "\"");        return null;    }    /**     * put方法真的精巧     * 每次都把新节点插在链表头,把first设置为一个新Node,next设置为刚才的first     * first = new Node(key, val, first);     **/    protected void put(String key, Integer val) {        if (first == null) {            first = new Node(key, val, first);            return;        } else {            for (Node x = first; x != null; x = x.next) {                if (key.equals(x.Key)) {                    x.val = val;                    return;                }            }            first = new Node(key, val, first);        }    }    protected Integer delete(String key) {        //如果这条链表本身就是空的        if (first == null) {            System.out.println("delete:Can't find the key" + "=" + "\"" + key + "\"");            return null;        }        Node x = first;        Node y = x;        //如果该条链表不是空的那就让这两个指针一前一后走到合适的位置        while (!key.equals(x.Key)) {            y = x;            x = x.next;            if (x == null) {                System.out.println("delete:Can't find the key" + "=" + "\"" + key + "\"");                return null;            }        }        Integer fuck = x.val;        //处理不同位置的x        if (x == first) {            first = null;        } else {            y.next = x.next;        }        return fuck;    }}
0 0