精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何輕松理解「鏈表」實現「LRU緩存淘汰算法

電子工程師 ? 來源:lq ? 2018-12-25 10:09 ? 次閱讀

前幾節學習了「鏈表」、「時間與空間復雜度」的概念,本節將結合「循環鏈表」、「雙向鏈表」與 「用空間換時間的設計思想」來設計一個很有意思的緩存淘汰策略:LRU緩存淘汰算法

三種最常見的鏈表結構

循環鏈表的概念

如上圖所示:單鏈表的尾結點指針指向空地址,表示這就是最后的結點了。而循環鏈表的尾結點指針是指向鏈表的頭結點。

因此循環鏈表是一種特殊的單鏈表。它跟單鏈表唯一的區別就在于尾結點。它像一個環一樣首尾相連,所以叫作「循環鏈表」。

循環鏈表的特點

和單鏈表相比,循環鏈表的優點是從鏈尾到鏈頭比較方便,當要處理的數據具有環型結構特點時,適合采用循環鏈表。

雙向鏈表概念

雙向鏈表也叫雙鏈表,是鏈表的一種,它的鏈接方向是雙向的,它的每個數據結點中都包含有兩個指針,分別指向直接后繼和直接前驅。

所以,從雙向鏈表中的任意一個結點開始,都可以很方便地訪問它的前驅結點和后繼結點。

雙向鏈表的數據結構中,會有兩個比較重要的參數:pre 和 next。

pre 指向前一個數據結構

next 指向下一個數據結構

單鏈表與雙鏈表的對比

雙向鏈表的特點

與單鏈表對比,雙鏈表需要多一個指針用于指向前驅節點,因此如果存儲同樣多的數據,雙向鏈表要比單鏈表占用更多的內存空間

雙鏈表的插入和刪除需要同時維護 next 和 prev 兩個指針。

雙鏈表中的元素訪問需要通過順序訪問,支持雙向遍歷,這就是雙向鏈表操作的靈活性根本

雙向鏈表的基本操作

1.添加元素。

與單向鏈表相對比雙向鏈表可以在 O(1) 時間復雜度搞定,而單向鏈表需要 O(n) 的時間復雜度。

雙向鏈表的添加元素包括頭插法和尾插法。

頭插法和尾插法

頭插法:將鏈表的左邊稱為鏈表頭部,右邊稱為鏈表尾部。頭插法是將右邊固定,每次新增的元素都在左邊頭部增加。

尾插法:將鏈表的左邊稱為鏈表頭部,右邊稱為鏈表尾部。尾插法是將左邊固定,每次新增都在鏈表的右邊最尾部。

2.查詢元素

查詢元素

雙向鏈表的靈活處就是知道鏈表中的一個元素結構就可以向左或者向右開始遍歷查找需要的元素結構。因此對于一個有序鏈表,雙向鏈表的按值查詢的效率比單鏈表高一些。因為,我們可以記錄上次查找的位置 p,每次查詢時,根據要查找的值與 p 的大小關系,決定是往前還是往后查找,所以平均只需要查找一半的數據。

3.刪除元素

在實際的軟件開發中,從鏈表中刪除一個數據無外乎這兩種情況:

刪除結點中“值等于某個給定值”的結點

刪除給定指針指向的結點

刪除元素

對于雙向鏈表來說,雙向鏈表中的結點已經保存了前驅結點的指針,刪除時不需要像單鏈表那樣遍歷。所以,針對第二種情況,單鏈表刪除操作需要 O(n) 的時間復雜度,而雙向鏈表只需要在 O(1) 的時間復雜度。

雙向循環鏈表

雙向循環鏈表

如圖所示,雙向循環鏈表的概念很好理解:「雙向鏈表」 + 「循環鏈表」的組合。

緩存淘汰策略

緩存是一種提高數據讀取性能的技術,在硬件設計、軟件開發中都有著非常廣泛的應用,比如常見的 CPU 緩存、數據庫緩存、瀏覽器緩存等等。

緩存的大小有限,當緩存被用滿時,哪些數據應該被清理出去,哪些數據應該被保留?這就需要緩存淘汰策略來決定。常見的策略有三種:先進先出策略 FIFO(First In,First Out)、最少使用策略 LFU(Least Frequently Used)、最近最少使用策略 LRU(Least Recently Used)。

在各個語言的第三方框架中都大量使用到了 LRU 緩存策略。程序員小吳接觸到的有Java中的 「 Mybatis 」,iOS中的 「YYCache」與「Lottie」等。

LRU緩存淘汰算法

LRU是最近最少使用策略的縮寫,是根據數據的歷史訪問記錄來進行淘汰數據,其核心思想是“如果數據最近被訪問過,那么將來被訪問的幾率也更高”。

LRU概念

鏈表實現LRU

將Cache的所有位置都用雙鏈表連接起來,當一個位置被命中之后,通過調整鏈表的指向,將該位置調整到鏈表頭的位置,新加入的Cache直接加到鏈表頭中。

這樣,在多次進行Cache操作后,最近被命中的,就會被向鏈表頭方向移動,而沒有命中的,而想鏈表后面移動,鏈表尾則表示最近最少使用的Cache。

當需要替換內容時候,鏈表的最后位置就是最少被命中的位置,我們只需要淘汰鏈表最后的部分即可。

鏈表實現LRU動畫演示

如果此數據之前已經被緩存在鏈表中了,通過遍歷得到這個數據對應的結點,并將其從原來的位置刪除,然后再插入到鏈表的頭部。

如果此數據沒有在緩存鏈表中,可以分為兩種情況:

如果此時緩存未滿,則將此結點直接插入到鏈表的頭部;

如果此時緩存已滿,則鏈表尾結點刪除,將新的數據結點插入鏈表的頭部。

鏈表實現LRU

通過動圖可以發現,如果緩存空間足夠大,那么存儲的數據也就足夠多,通過緩存中命中數據的概率就越大,也就提高了代碼的執行速度。這就是空間換時間的設計思想。

對于程序開發來說,時間復雜度和空間復雜度是可以相互轉化的。說通俗一點,就是:

對于執行的慢的程序,可以通過消耗內存(即構造新的數據結構)來進行優化;

而消耗內存的程序,可以通過消耗時間來降低內存的消耗。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據結構
    +關注

    關注

    3

    文章

    573

    瀏覽量

    40092
  • 鏈表
    +關注

    關注

    0

    文章

    80

    瀏覽量

    10547

原文標題:看動畫輕松理解「鏈表」實現「LRU緩存淘汰算法」

文章出處:【微信號:rgznai100,微信公眾號:rgznai100】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    LRU緩存模塊最佳實踐

    LRU(Least Recently Used)是一種緩存替換算法,它的核心思想是當緩存滿時,替換最近最少使用的數據。在實際應用中,LRU
    的頭像 發表于 09-30 16:47 ?862次閱讀

    Redis的LRU實現和應用

    在編程中,計數器是一種基本但強大的工具,用于跟蹤和管理數據和資源。本文將深入探討不同類型的計數器的應用,從Redis的LRU(最近最少使用)緩存淘汰算法
    的頭像 發表于 12-15 09:24 ?570次閱讀

    【原創】Android開發—Lru核心數據結構實現突破緩存框架

    【原創】Android開發—Lru核心數據結構實現突破緩存框架回復即可獲取下載鏈接[hide=d15]鏈接:http://pan.baidu.com/s/1c2BfjsW 密碼:bta5 更多學習資料加Q:1352716312,
    發表于 06-21 16:58

    《CDN 之我見》系列二:原理篇(緩存、安全)

    Hash 運算都得到同一個余數),則性能與單鏈表無異,查找時間復雜度是 O(n)。如果磁盤空間不夠了怎么辦?使用基于訪問熱度的內容淘汰算法,例如 FIFO、LRU、LFU、SLRU、
    發表于 06-12 16:59

    架構設計應用級緩存回收策略

    下。FIFO(First In First Out):先進先出算法,即先放入緩存的先被移除。LRU(Least Recently Used):最近最少算法,使用時間距離現在最久的那個被
    發表于 01-14 17:08

    算法與數據結構——雙向鏈表

    第三章為算法與數據結構,本文為3.3 雙向鏈表
    的頭像 發表于 09-19 17:56 ?7263次閱讀
    <b class='flag-5'>算法</b>與數據結構——雙向<b class='flag-5'>鏈表</b>

    如何進行單鏈表的查找、插入與刪除的詳細介紹包括了算法和源程序

    鏈表的查找、插入與刪除。設計算法實現線性結構上的單鏈表的產生以及元素的查找、插入與刪除。具體實現要求:
    發表于 07-16 08:00 ?22次下載
    如何進行單<b class='flag-5'>鏈表</b>的查找、插入與刪除的詳細介紹包括了<b class='flag-5'>算法</b>和源程序

    帶你輕松理解數據結構與算法系列

      主要使用圖片來描述常見的數據結構和算法輕松閱讀并理解掌握。本系列包括各種堆、各種隊列、各種列表、各種樹、各種圖、各種排序等等。
    發表于 08-01 17:34 ?2次下載
    帶你<b class='flag-5'>輕松</b><b class='flag-5'>理解</b>數據結構與<b class='flag-5'>算法</b>系列

    一文讀懂緩存淘汰算法:LFU 算法

    實現難度上來說,LFU 算法的難度大于 LRU 算法,因為 LRU 算法相當于把數據按照時間排
    的頭像 發表于 08-25 17:37 ?9859次閱讀
    一文讀懂<b class='flag-5'>緩存</b><b class='flag-5'>淘汰</b><b class='flag-5'>算法</b>:LFU <b class='flag-5'>算法</b>

    谷歌在內存方面依賴于per memcg lru lock

    能力。 作為世間最流行的操作系統Linux, 內核使用LRU, Last Recent Used 鏈表來管理全部用戶使用的內存,用一組鏈表串聯起一個個的內存頁,并且使用lru lock
    的頭像 發表于 01-15 14:00 ?1890次閱讀
    谷歌在內存方面依賴于per memcg <b class='flag-5'>lru</b> lock

    設計并實現一個滿足LRU約束的數據結構

    LRUCache(int capacity)` 以 **「正整數」** 作為容量 `capacity` 初始化 `LRU` 緩存
    的頭像 發表于 06-07 17:05 ?959次閱讀
    設計并<b class='flag-5'>實現</b>一個滿足<b class='flag-5'>LRU</b>約束的數據結構

    基于LRU-K模型如何實現高效的元數據緩存

    對于存儲來說,性能是繞不開的話題。當提到性能,可靠、高效的緩存策略是極其重要的。
    的頭像 發表于 06-29 15:05 ?850次閱讀
    基于<b class='flag-5'>LRU</b>-K模型如何<b class='flag-5'>實現</b>高效的元數據<b class='flag-5'>緩存</b>?

    Redis的LRU與LFU算法實現

    Redis是一款基于內存的高性能NoSQL數據庫,數據都緩存在內存里, 這使得Redis可以每秒輕松地處理數萬的讀寫請求。
    的頭像 發表于 07-11 09:48 ?1071次閱讀
    Redis的<b class='flag-5'>LRU</b>與LFU<b class='flag-5'>算法</b><b class='flag-5'>實現</b>

    redis的lru原理

    Redis是一種基于內存的鍵值數據庫,它使用了LRU(Least Recently Used)算法來進行緩存的數據淘汰LRU
    的頭像 發表于 12-05 09:56 ?604次閱讀

    關于LRU(Least Recently Used)的邏輯實現

    Used)算法是一種常用的緩存淘汰策略,其核心思想是:如果一個數據在最近一段時間內沒有被訪問到,那么在未來它被訪問的可能性也很小。因此,當緩存滿了的時候,最久未使用的數據會被
    的頭像 發表于 11-12 11:47 ?166次閱讀
    關于<b class='flag-5'>LRU</b>(Least Recently Used)的邏輯<b class='flag-5'>實現</b>