golang LRU
package main
type Node struct {
Key,Value int
//双链表
Pre,Next *Node
}
type LruCache struct {
//现有元素数量
Size int
//lru容量
Capacity int
//map存储链表节点,查询速度O(1)
HashMap map[int]*Node
//哨兵头尾,方便节点插入初始位置
Dummy,Tail *Node
}
//初始化新节点
func InitNode(key,value int)*Node {
return &Node{
Key: key,
Value: value,
}
}
//初始化Lru
func (m*LruCache)InitLruCache(capacity int)LruCache {
l:=LruCache{
Capacity: capacity,
HashMap: make(map[int]*Node,capacity),
Dummy: InitNode(0,0),
Tail: InitNode(0,0),
}
//头尾连接
l.Dummy.Next=l.Tail
l.Tail.Pre = l.Dummy
return l
}
//两个基础函数,增加到头,移除节点,方便使用
//增加到头部
func (m*LruCache)AddToHead(n*Node) {
//双向链表,两边都增加
n.Next = m.Dummy.Next
n.Pre = m.Dummy
m.Dummy.Next.Pre = n
m.Dummy.Next = n
}
//移除节点
func (m*LruCache)Remove(n*Node) {
n.Pre.Next = n.Next
n.Next.Pre = n.Pre
}
//节点移动,删除节点,移动到头部
func (m*LruCache)MoveHead(n*Node) {
m.MoveHead(n)
m.AddToHead(n)
}
//超过容量,删除最后一个
//其实是删除tail的pre,返回node,方便移除map中的数据
func (m*LruCache)DelTail()*Node {
n:=m.Tail.Pre
m.Remove(n)
return n
}
//主要的get和put函数
//get key获取value 没有返回-1
func (m*LruCache)Get(key int)int {
if _,ok :=m.HashMap[key];!ok{
return -1
}
//使用到,移到头,返回value
n:=m.HashMap[key]
m.MoveHead(n)
return n.Value
}
//put 存在直接改值,不存在,加入判断是否超出长度,超出删尾部
func (m*LruCache)Put(key,value int) {
if _,ok:=m.HashMap[key];ok{
n:=m.HashMap[key]
n.Value = value
m.MoveHead(n)
}else{
if m.Size+1>m.Capacity{
node:=m.DelTail()
//上面是移除链表,记得移除map中的数据
delete(m.HashMap,node.Key)
m.Size--
}
n:=InitNode(key,value)
m.HashMap[key] = n
//map添加元素,但是链表未增加节点,所以调用AddToHead,添加节点到链表即可,不要使用MoveHead
m.AddToHead(n)
m.Size++
}
}
LFU c++
实现方式有很多
struct Node{
int key;
int value;
int freq;
Node(int k,int v,int f):key(k),value(v),freq(f){}
};
class LFUCache {
public:
int cap,minFreq;
unordered_map<int,list<Node>::iterator>keys;
unordered_map<int,list<Node>>freqs;
LFUCache(int capacity) {
cap = capacity;
minFreq = 0;
keys.clear();
freqs.clear();
}
int get(int key) {
if(cap==0)return -1;
auto it = keys.find(key);
if(it==keys.end())return -1;
//正常流程
list<Node>::iterator p = it->second;
int value = p->value,fre = p->freq;
freqs[fre].erase(p);//去除迭代器
if(freqs[fre].size()==0)
{
freqs.erase(fre);
if(fre==minFreq)minFreq++;
}
//增加新的
freqs[fre+1].push_front(Node(key,value,fre+1));
keys[key] = freqs[fre+1].begin();//放的是迭代器
return value;
}
void put(int key, int value) {
if(cap==0)return;
//存在,不存在
auto it = keys.find(key);
if(it==keys.end())
{
if(keys.size()==cap)
{
auto p =freqs[minFreq].back();//最小的尾部
keys.erase(p.key);
freqs[minFreq].pop_back();
if(freqs[minFreq].size()==0)//移除后最小没了,去除此节点
{
freqs.erase(minFreq);
}
}
//容量判断之后
freqs[1].push_front(Node(key,value,1));
keys[key] = freqs[1].begin();//key放迭代器?
minFreq = 1;
}else{
//存在
list<Node>::iterator p = it->second;//获取迭代器
int fre = p->freq;
freqs[fre].erase(p);//删除需要迭代器
if(freqs[fre].size()==0)
{
freqs.erase(fre);
if(fre==minFreq)minFreq++;
}
freqs[fre+1].push_front(Node(key,value,fre+1));
keys[key] = freqs[fre+1].begin();
}
}
};
/**
* Your LFUCache object will be instantiated and called as such:
* LFUCache* obj = new LFUCache(capacity);
* int param_1 = obj->get(key);
* obj->put(key,value);
*/