學習筆記1 c 實現LRU演算法

2021-06-20 04:15:59 字數 3975 閱讀 6729

leetcode oj上有一道題目,要程式設計實現cache的lru演算法,剛看到這道題的時候,我想到了用佇列來做,但是若用單鏈表來做,必須要儲存尾節點的上乙個節點指標,才能實現快速增加一條資料,程式設計起來很不方便,所以我採用了雙端佇列實現,為了處理方便,儲存兩個帶節點指標,乙個節點的next指向頭結點,另乙個節點next指向尾節點。

lru演算法中還要求將已存在的節點放入隊尾或者插入節點時要判斷此節點是不是存在,所以我使用hash表來快速的定位到此節點,所以就有節點定義

struct node

};

hash定義:

#define max 10000//hash表最大長度

#define mod 9991//大質數

node *hash[max][20];

int len[max];//對應每個鍵值的長度

hash函式為:

int _hash(int key)

雙端佇列(dqueue)要提供插入乙個節點(insert)、刪除頭結點(delhead)、獲取佇列大小(size)、根據key值獲取節點的value值功能(find);

其中插入節點時需要判斷該節點是不是存在,若存在,需要將其放到隊尾,並給其賦新值;根據key值獲取節點value值時也要判斷節點是否存在,若存在也需將其放入隊尾,並返回該節點value值。所以我增加了乙個search函式,

函式宣告為:

node * search(int key);

該函式功能為,在hash表中查詢鍵值為key的節點,若找不到返回null,找到時將該節點拿出來插入到隊尾,並返回該節點,具體實現為:

node * search(int key)

if(t->next==null)

t->pre->next=t->next;//既不是頭結點也不是尾節點,只需要對tail指標進行操作

t->next->pre=t->pre;

t->pre=tail->next;

tail->next->next=t;

t->next=null;

tail->next=t;

return t;

} }return null;

}

所以整個dqueue雙端佇列類實現如下:

class dqueue

node * search(int key)

if(t->next==null)

t->pre->next=t->next;

t->next->pre=t->pre;

t->pre=tail->next;

tail->next->next=t;

t->next=null;

tail->next=t;

return t;

}} return null;

}public:

dqueue()

int insert(int key,int val)

node *t=new node(key,val);

if(!size)

t->pre=tail->next;

if(tail->next!=null)tail->next->next=t;

int pos=_hash(t->key);

hash[pos][len[pos]++]=t;

tail->next=t;

size++;

return 1;

} int delhead()

return 0;

} int find(int key)

int size()

};

lru類實現就比較簡單了:

class lrucache

int get(int key)

void set(int key,int value)

}};

整個**實現加測試程式如下:

#include #include #include #include #include #include #include #include #include #include using namespace std;

#define max 10000

#define mod 9991

struct node

};class dqueue

node * search(int key)

if(t->next==null)

t->pre->next=t->next;

t->next->pre=t->pre;

t->pre=tail->next;

tail->next->next=t;

t->next=null;

tail->next=t;

return t;

}} return null;

}public:

dqueue()

int insert(int key,int val)

node *t=new node(key,val);

if(!size)

t->pre=tail->next;

if(tail->next!=null)tail->next->next=t;

int pos=_hash(t->key);

hash[pos][len[pos]++]=t;

tail->next=t;

size++;

return 1;

} int delhead()

return 0;

} int find(int key)

int size()

};class lrucache

int get(int key)

void set(int key,int value)

}};void test()//測試程式

};

整個實現起來就輕鬆了許多,略作修改後的全部**貼上:

#include #include #include #include #include #include #include #include #include #include using namespace std;

#define max 10000

#define mod 9991

struct node

};class dqueue

node * search(int key)

} return null;

}public:

dqueue()

int insert(int key,int val)

node *t=new node(key,val);

t->next=head;

t->pre=head->pre;

head->pre->next=t;

head->pre=t;

int pos=_hash(key);

hash[pos][len[pos]++]=t;

size++;

return 1;

} int delhead()

int find(int key)

int size()

};class lrucache

int get(int key)

void set(int key,int value)

}};void test()//測試程式

{ //freopen("c:\\in.txt","r",stdin);

lrucache p(10);

p.set(10,13),p.set(3,17),p.set(6,11),p.set(10,5),p.set(9,10);

cout<

學習筆記1 C 總結

溫故而知新,總結過去,展望未來!一 函式過載 c 中允許通過換名機制實現函式過載,函式過載是指在相同的作用域中,允許存在多個函式名相同的函式 存在條件 他們的引數個數 引數型別 引數排列必須不同,返回值型別不做要求 二 異常處理 所謂異常,就是程式執行到某乙個函式或者方法內部時候,出現了與程式涉及流...

1 C 學習筆記 記憶體模型

c 和c語言對於變數定義的方式型別,定義的不同方式確定了變數的生存週期 作用範圍以及可以被誰使用的 許可權 問題。一般來講我們把儲存的持續性簡稱為變數在程式中定義的位置,有以下三個位置 1.自動儲存持續性 簡稱自動變數,該變數定義在具體的函式塊中,並且不加 static 這種修飾符,該類變數從函式被...

演算法競賽入門經典 學習筆記1(c語言)

本書是基於c語言的 是在vs2012利用c 編寫的 第一章 一.基本表示式的輸入輸出 1.整數 整數 整數 2.整數與浮點數的商 浮點數 3.整數 浮點數 浮點數 實質上是整數轉化為浮點數在做的減法 c基礎 在c中大小寫字母代表的含義是不同的 列子1.include int main printf ...