LRU算法
C++代码实现
#include <vector>
#include <cstdio>
#include <unordered_map>
struct ListNode {
ListNode *prev;
ListNode *next;
int val;
ListNode() = default;
ListNode(int v): val(v) {}
};
class LRUReplacer {
public:
LRUReplacer(int capacity): capacity_(capacity), size_(0) {
head_ = new ListNode();
tail_ = new ListNode();
tail_->next = head_;
head_->prev = tail_;
}
~LRUReplacer() {
while (!IsEmpty()) {
RemoveFromHead();
}
delete head_;
delete tail_;
}
bool IsEmpty() {
return size_ == 0 && tail_->next == head_ && head_->prev == tail_;
}
bool IsFull() {
return size_ == capacity_;
}
void Add(int page) {
printf("add %d, ", page);
// hit
if (ht_.count(page)) {
printf(" hit, ");
ListNode *n = ht_[page];
RemoveNode(n);
AddToTail(n);
Print();
return;
}
// not hit
printf("not hit, ");
ListNode *n = new ListNode(page);
if (size_ < capacity_) {
AddToTail(n);
ht_[page] = n;
} else {
RemoveFromHead();
AddToTail(n);
}
Print();
}
private:
int capacity_;
int size_;
ListNode *tail_;
ListNode *head_;
std::unordered_map<int, ListNode *> ht_;
void AddToTail(ListNode *n) {
ListNode *temp = tail_->next;
n->next = temp;
temp->prev = n;
tail_->next = n;
n->prev = tail_;
size_++;
}
void RemoveFromHead() {
ListNode *temp1 = head_->prev;
ListNode *temp2 = temp1->prev;
temp2->next = head_;
head_->prev = temp2;
ht_.erase(temp1->val);
delete temp1;
size_--;
}
void RemoveNode(ListNode *n) {
ListNode *temp1 = n->prev;
ListNode *temp2 = n->next;
temp1->next = temp2;
temp2->prev = temp1;
size_--;
}
void Print() {
printf("size: %d, pages: ", size_);
for (ListNode *n = head_->prev; n != tail_; n = n->prev) {
printf("%d ", n->val);
}
printf("\n");
}
};
int main() {
std::vector<int> pages{7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 2};
LRUReplacer lru(3);
for (int page : pages) {
lru.Add(page);
}
}
运行结果:
add 7, not hit, size: 1, pages: 7
add 0, not hit, size: 2, pages: 7 0
add 1, not hit, size: 3, pages: 7 0 1
add 2, not hit, size: 3, pages: 0 1 2
add 0, hit, size: 3, pages: 1 2 0
add 3, not hit, size: 3, pages: 2 0 3
add 0, hit, size: 3, pages: 2 3 0
add 4, not hit, size: 3, pages: 3 0 4
add 2, not hit, size: 3, pages: 0 4 2
add 3, not hit, size: 3, pages: 4 2 3
add 0, not hit, size: 3, pages: 2 3 0
add 2, not hit, size: 3, pages: 3 0 2