日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c均值算法的设计与实现_如何使用C链表实现 LRU 算法

發布時間:2023/12/4 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c均值算法的设计与实现_如何使用C链表实现 LRU 算法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

什么是 LRU 算法

LRU 是一種緩存淘汰策略。計算機的緩存容量有限,如果緩存滿了就要刪除一些內容,給新的內容騰位置。但是要刪除哪些內容呢?我們肯定希望刪掉那些沒有用的緩存,而把有用的數據繼續留在緩存中,方便之后繼續使用。

LRU 的全稱是 Least Recently Used,也就是說我們認為最近使用過的數據應該是有用的,很久都沒用過的數據應該是無用的,緩存滿了就優先刪除那些很久沒有用過的數據。

LRU 算法的特點

首先是緩存的大小是有限的。每次從緩存當中獲取數據的時候,如果獲取成功會將數據移動到最頭部。同時新添加的元素也是在頭部。當緩存大小達到上限之后,添加元素時會刪除最久未使用的元素,也就是鏈表的最后一個元素,然后將新的元素插入在鏈表頭。

LRU 的應用場景

LRU 算法可以用來管理我們的緩存數據。控制我們的緩存大小,用較少的緩存空間達到更高的緩存數據。舉例來說我們可以將一些不容易發生變化的數據且頭部效應表中的數據加入到緩存當中。

編碼實現

結構定義

#include?
#include?
#include?

//?默認容量
#define?N?10

//?表示這個鏈表的長度信息
int?len?=?0;

//當前鏈表的元素個數信息
int?count?=?0;

typedef?struct?Node
{
????/*?data?*/
????char?*key;
????char?*value;

????struct?Node?*next;
????struct?Node?*prev;
}?Node;

//?鏈表的頭節點和尾節點
struct?Node?*head;
struct?Node?*tail;

//?函數預聲明
//?創建節點
Node?*createNode(char?*key,?char?*value);
//?插入節點到頭部
void?insertHead(Node?*node);
//?移除尾部節點
void?removeTail();
//?添加節點操作
void?add(char?*key,?char?*value);
//?刪除鏈表中的一個節點
Node?*deleteNode(Node?*node);
//?獲取指定key的值
char?*get(char?*key);
//?銷毀數據
void?destory();

插入操作

//?獲取一個元素
void?add(char?*key,?char?*value){
????Node?*node?=?createNode(key,?value);
????//第一個元素
????if?(head?==?NULL)
????{
????????insertHead(node);
????????return;
????}

????//判斷整個鏈表中是否存在整個元素
????Node?*now?=?deleteNode(node);

????//?如果找到了元素?將元素移動至末尾?結束方法
????if?(now?!=?NULL)
????{
????????//?設置新的值
????????now->value?=?value;
????????insertHead(now);
????????return;
????}

????//?此時鏈表中是不存在這個元素
????//?判斷鏈表的長度
????if?(count?>=?len)
????{
????????removeTail();
????}

????//?將新元素添加至末尾
????insertHead(node);
????return;
}

獲取操作

char?*get(char?*key){
????if?(key?==?NULL)
????{
????????return?NULL;
????}

????//?尋找元素
????Node?*node?=?createNode(key,?NULL);
????Node?*now?=?deleteNode(node);

????//?釋放空間
????free(node);

????//?元素存在
????if?(now?!=?NULL)
????{
????????//將元素調整到末尾
????????insertHead(now);
????????return?now->value;
????}
????return?NULL;
}

基本操作函數


//?創建一個節點
Node?*createNode(char?*key,?char?*value){
????Node?*node?=?(Node?*)malloc(sizeof(Node));
????node->key?=?key;
????node->value?=?value;
????node->prev?=?node->next?=?NULL;
????return?node;
}

//?將節點插入到頭節點部分
void?insertHead(Node?*node){
????//?元素為空時
????if?(head?==?NULL)
????{
????????tail?=?head?=?node;
????????count++;
????????return;
????}
????node->next?=?head;
????head->prev?=?node;
????//?移動鏈表的末尾指針
????head?=?node;
????//?計數
????count++;
}

//?移除
void?removeTail(){
????//移除最久未使用的那個元素
????Node?*now?=?tail;
????if?(now?!=?NULL)
????{
????????//?獲取前一個節點
????????Node?*p?=?now->prev;

????????if?(p?!=?NULL)
????????{
????????????//?斷開當前節點?同時移動尾節點
????????????p->next?=?NULL;
????????????tail?=?p;
????????}
????????else
????????{
????????????head?=?tail?=?NULL;
????????}
????????//?當前節點置空
????????now->prev?=?now->next?=?NULL;
????????//?元素減少
????????count--;
????????//?釋放空間
????????free(now);
????}
}

//?鏈表中刪除一個節點??刪除成功返回被刪除節點
Node?*deleteNode(Node?*node){
????Node?*now?=?head;
????while?(now?!=?NULL)
????{
????????//?存在節點
????????if?(strcmp(now->key,?node->key)?==?0)
????????{
????????????//?獲取前后節點
????????????Node?*p?=?now->prev;
????????????Node?*n?=?now->next;

????????????//?更新指向
????????????if?(n?!=?NULL)
????????????{
????????????????n->prev?=?p;
????????????}
????????????else
????????????{
????????????????tail?=?p;
????????????}

????????????if?(p?!=?NULL)
????????????{
????????????????p->next?=?n;
????????????}
????????????else
????????????{
????????????????head?=?n;
????????????}
????????????//當前節點置空
????????????now->prev?=?NULL;
????????????now->next?=?NULL;
????????????count--;
????????????break;
????????}
????????now?=?now->next;
????}
????return?now;
}

//?銷毀數據
void?destory(){
????Node?*node?=?head;
????while?(node?!=?NULL)
????{
????????Node?*n?=?node;
????????free(n);
????????node?=?node->next;
????}
????len?=?0;
????count?=?0;
????head?=?tail?=?NULL;
}

//?從頭節點開始打印整個鏈表
void?printLink(){
????Node?*now?=?head;
????while?(now?!=?NULL)
????{
????????printf("[key=%s,value=%s]",?now->key,?now->value);
????????now?=?now->next;
????}
????printf("\n");
}

最后的測試函數

int?main(){
????init(5);
????add("1",?"1");
????add("2",?"2");
????printLink();
????char?*res?=?get("1");
????printLink();
????printf("value=%s\n",?res);
????add("3",?"3");
????add("4",?"4");
????add("5",?"5");
????add("6",?"6");
????printLink();
????res?=?get("1");
????printLink();
????destory();
????return?0;
}

//?輸出結果:
/*
[key=2,value=2][key=1,value=1]
[key=1,value=1][key=2,value=2]
value=1
[key=6,value=6][key=5,value=5][key=4,value=4][key=3,value=3][key=1,value=1]
[key=1,value=1][key=6,value=6][key=5,value=5][key=4,value=4][key=3,value=3]
*/

以上就是一個鏈表實現 LRU 算法的大體代碼。

已將代碼上傳至https://gitlab.com/BitLegend/c-data-structure.git

感謝你能看到這里,歡迎關注我的公眾號:BitLegend,我們下期見!

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的c均值算法的设计与实现_如何使用C链表实现 LRU 算法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。