这一篇实现主要实现了最不常用算法
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
struct ColumnNode {
int val;
string key;
unsigned int freq;
ColumnNode* last;
ColumnNode* next;
ColumnNode(string key, int value)
: val(value), key(key), freq(1), last(nullptr), next(nullptr)
{ }
};
struct RowNode {
ColumnNode* head;
ColumnNode* tail;
RowNode* last;
RowNode* next;
RowNode(ColumnNode* node)
: last(nullptr), next(nullptr) {
if (node == nullptr) {
return;
}
head = tail = node;
}
void addColumnNode(ColumnNode* node) {
if (node == nullptr) {
return;
}
node->next = head;
head->last = node;
head = node;
}
void deleteColumnNode(ColumnNode* node) {
if (node == nullptr) {
return;
}
if (head == tail) {
head = tail = nullptr;
}
else {
if (node == head) {
head = head->next;
head->last = nullptr;
}
else if (node == tail) {
tail = tail->last;
tail->next = nullptr;
}
else {
node->last->next = node->next;
node->next->last = node->last;
}
}
node->last = node->next = nullptr;
}
bool columnListIsEmpty() {
return head == nullptr;
}
~RowNode() {
while (head) {
tail = head;
head = head->next;
delete tail;
}
}
};
class LFUCache {
public:
LFUCache(int capacity)
: capacity(capacity), size(0), rowListHead(nullptr)
{ }
void moveNode(ColumnNode* node, RowNode* oldRowNode) {
oldRowNode->deleteColumnNode(node);
RowNode* nextRowNode = oldRowNode->next;
RowNode* preRowNode = motifyHeadList(oldRowNode);
if (nextRowNode == nullptr) {
RowNode* newRowNode = new RowNode(node);
if (preRowNode != nullptr) {
preRowNode->next = newRowNode;
}
newRowNode->last = preRowNode;
if (rowListHead == nullptr) {
rowListHead = newRowNode;
}
heads.insert(pair<ColumnNode*, RowNode*>(node, newRowNode));
}
else {
if (nextRowNode->head->freq == node->freq) {
nextRowNode->addColumnNode(node);
heads.insert(pair<ColumnNode*, RowNode*>(node, nextRowNode));
}
else {
RowNode* newRowNode = new RowNode(node);
newRowNode->next = nextRowNode;
nextRowNode->last = newRowNode;
newRowNode->last = preRowNode;
if (preRowNode) {
preRowNode->next = newRowNode;
}
if (rowListHead == nextRowNode) {
rowListHead = newRowNode;
}
heads.insert(pair<ColumnNode*, RowNode*>(node, newRowNode));
}
}
}
RowNode* motifyHeadList(RowNode* rowNode) {
if (rowNode->columnListIsEmpty()) {
if (rowNode == rowListHead) {
rowListHead = rowListHead->next;
if (rowListHead) {
rowListHead->last = nullptr;
}
}
else {
rowListHead->last->next = rowListHead->next;
if (rowListHead->next) {
rowListHead->next->last = rowListHead->last;
}
}
RowNode* res = rowNode->last;
delete rowNode;
return res;
}
return rowNode;
}
void set(string key, int value) {
if (records.count(key)) {
ColumnNode* node = records.at(key);
node->val = value;
node->freq++;
RowNode* rowNode = heads.at(node);
moveNode(node, rowNode);
}
else {
if (capacity == size) {
ColumnNode* columnNode = rowListHead->tail;
rowListHead->deleteColumnNode(columnNode);
records.erase(key);
RowNode* rowNode = heads.at(columnNode);
heads.erase(columnNode);
motifyHeadList(rowNode);
delete columnNode;
size--;
}
ColumnNode* node = new ColumnNode(key, value);
if (rowListHead == nullptr) {
rowListHead = new RowNode(node);
}
else {
if (rowListHead->head->freq == 1) {
rowListHead->addColumnNode(node);
}
else {
RowNode* newRowNode = new RowNode(node);
newRowNode->next = rowListHead;
rowListHead->last = newRowNode;
rowListHead = newRowNode;
}
}
records.insert(pair<string, ColumnNode*>(key, node));
heads.insert(pair<ColumnNode*, RowNode*>(node, rowListHead));
size++;
}
}
int get(string key) {
if (records.count(key) == 0) {
return INT_MIN;
}
ColumnNode* columnNode = records.at(key);
columnNode->freq++;
RowNode* rowNode = heads.at(columnNode);
moveNode(columnNode, rowNode);
return columnNode->val;
}
~LFUCache() {
while (rowListHead) {
RowNode* rowNode = rowListHead;
rowListHead = rowListHead->next;
delete rowNode;
}
}
private:
int size;
int capacity;
RowNode* rowListHead;
unordered_map<string, ColumnNode*> records;
unordered_map<ColumnNode*, RowNode*> heads;
};
int main() {
LFUCache lFUCache(3);
lFUCache.set(string("A"), 1);
lFUCache.set(string("B"), 2);
lFUCache.set(string("C"), 3);
lFUCache.get(string("A"));
lFUCache.set(string("D"), 4);
system("pause");
return 0;
}
如有侵权,请联系删除,如有错误,欢迎大家指正,谢谢