本着自己实操的原则..手撸了一遍算法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;
}
}