leetcode面试题 16.25. LRU缓存。之前写过一篇根本不算HASH的HASH,也总结过UT_hash_handle
现在为了做这道题,发现UT哈希是按照插入顺序存储节点的。
另外也用双向链表做了一次。
1. UT哈希方法如下:
因为添加就可以把信息放到hash的尾巴,那么需要更新信息:只需要先删除节点,再添加节点
HASH_FIND_INT(obj->user, &key, s);
if(s == NULL) {
return -1;
}
HASH_DEL(obj->user, s);
HASH_ADD_INT(obj->user, id, s);
如果当前信息已经达到容量,那么删除最旧的信息:需要删除obj->user节点,即是头结点;
int currNum = HASH_COUNT(obj->user);
if(currNum > obj->maxNum) {
s = obj->user;
HASH_DEL(obj->user, s);
free(s);
}
以及神奇的是我删除了这个头指针,为什么还是可以通过obj->user去找hash关系
Delete can change the pointer
The hash table pointer (which initially points to the first item added to the hash) can change in response to HASH_DEL (i.e. if you delete the first item in the hash table).
2. 双向链表思路如下:
typedef struct Info_ {
int id;
int value;
struct Info_ *pre;
struct Info_ *next;
UT_hash_handle hh;
} Info;
typedef struct {
int MaxNum;
Info *user; /*hash自带的user*/
Info *total; /*给一次性申请空间用*/
Info head; /*双向链表所需要的“头”*/
} LRUCache;
1、Create函有个点,就是申请空间的时候一次性把空间申请好给total;
2、GET函数,就是如果能查找到的情况下;【更新】节点
3、PUT函数,如果能找到,那么【更新】value和节点;
如果不能找到,看当前空间是否满,如果满了,那么替换最next的函数,如果没满,直接加进去并且【插入】节点;
LRUCache* lRUCacheCreate(int capacity) {
LRUCache* obj = (LRUCache*)malloc(sizeof(LRUCache));
if (obj == NULL) {
return NULL;
}
obj->user = NULL;
obj->total = (Info*)malloc(sizeof(Info) * capacity);
obj->head.next = NULL;
obj->MaxNum = capacity;
memset(obj->total, 0, sizeof(Info)*capacity);
return obj;
}
int lRUCacheGet(LRUCache