HashMap+雙向鏈表,看完之後,再也不怕頭條面試官讓我手撕LRU算法了

數據結構:

  • 雙向鏈表作爲LRU隊列
  • 鏈表尾指針降低添加和修改時間複雜度爲O(1)
  • HashMap存儲每個元素的地址,降低修改時間複雜度爲O(1)

添加、訪問、刪除操作:

  • 添加:直接通過尾指針加到隊尾,如果大於容量,刪除隊頭節點
  • 修改:通過HashMap拿到對應節點的地址,通過前後指針刪除當前節點,再通過尾指針加到隊尾
  • 刪除:通過HashMap拿到對應節點的地址,通過前後指針刪除當前節點

代碼:

<?php
class ListQueue
{
    public $maxCount = 3;
    public $head = null;
    public $tail = null;
    public $count = 0;

    public function add($key, $value)
    {
        $node = new Node();
        $node->key = $key;
        $node->value = $value;
        if ($this->head === null){
            $this->head = $node;
        }else{
            $node->pre = $this->tail;
            $this->tail->next = $node;
        }
        $this->tail = $node;

        $this->incrCount();
        return $node;
    }

    public function del($node)
    {
        $pre = $node->pre;
        $next = $node->next;
        if ($pre === null){
            $next->pre = null;
            $this->head = $next;
        }else{
            $pre->next = $node->next;
            $next->pre = $pre;
        }

        $node->next = null;

        $this->decrCount();
    }

    public function delHead()
    {
        $oldHead = $this->head;
        $this->head = $oldHead->next;
        $this->head->pre = null;
        $this->decrCount();
        return $oldHead->key;
    }

    public function incrCount()
    {
        $this->count++;
    }

    public function decrCount()
    {
        $this->count > 0 && $this->count--;
    }

    public function checkMax()
    {
        return $this->count > $this->maxCount;
    }

}
class Node
{
    public $key;
    public $value;
    public $pre;
    public $next;
}
class Lru
{
    public $list = null;
    public $hashMap = [];

    public function __construct()
    {
        $this->list = new ListQueue();
    }

    public function add($key, $value)
    {
        $node = $this->list->add($key, $value);
        $this->hashMap[$key] = $node;

        if ($this->list->checkMax()){
            $headKey = $this->list->delHead();
            unset($this->hashMap[$headKey]);
        }
    }

    public function get($key){
        $node = $this->hashMap[$key];
        if (!$node){
            return false;
        }

        $this->list->del($node);
        $node = $this->list->add($key, $node->value);
        $this->hashMap[$key] = $node;

        return $node->value;
    }

    public function update($key, $value){
        $node = $this->hashMap[$key];
        if (!$node){
            return false;
        }
        $this->list->del($node);
        $node = $this->list->add($key, $value);
        $this->hashMap[$key] = $node;
    }

}

$lru = new Lru();
$lru->add('why', 'why');
$lru->add('jzm', 'jzm');
$lru->add('ymt', 'ymt');
$lru->get('jzm');
$lru->update('why', 'why111');
$lru->add('123', '123');
print_r($lru->list);


運行結果:

[why@whydeMacBook-Pro] ~/Desktop/php$php lru.php 
Array
(
    [why] => Node Object
        (
            [key] => why
            [value] => why111
            [pre] => Node Object
                (
                    [key] => jzm
                    [value] => jzm
                    [pre] => 
                    [next] => Node Object
 *RECURSION*
                )

            [next] => Node Object
                (
                    [key] => 123
                    [value] => 123
                    [pre] => Node Object
 *RECURSION*
                    [next] => 
                )

        )

    [jzm] => Node Object
        (
            [key] => jzm
            [value] => jzm
            [pre] => 
            [next] => Node Object
                (
                    [key] => why
                    [value] => why111
                    [pre] => Node Object
 *RECURSION*
                    [next] => Node Object
                        (
                            [key] => 123
                            [value] => 123
                            [pre] => Node Object
 *RECURSION*
                            [next] => 
                        )

                )

        )

    [123] => Node Object
        (
            [key] => 123
            [value] => 123
            [pre] => Node Object
                (
                    [key] => why
                    [value] => why111
                    [pre] => Node Object
                        (
                            [key] => jzm
                            [value] => jzm
                            [pre] => 
                            [next] => Node Object
 *RECURSION*
                        )

                    [next] => Node Object
 *RECURSION*
                )

            [next] => 
        )

)
ListQueue Object
(
    [maxCount] => 3
    [head] => Node Object
        (
            [key] => jzm
            [value] => jzm
            [pre] => 
            [next] => Node Object
                (
                    [key] => why
                    [value] => why111
                    [pre] => Node Object
 *RECURSION*
                    [next] => Node Object
                        (
                            [key] => 123
                            [value] => 123
                            [pre] => Node Object
 *RECURSION*
                            [next] => 
                        )

                )

        )

    [tail] => Node Object
        (
            [key] => 123
            [value] => 123
            [pre] => Node Object
                (
                    [key] => why
                    [value] => why111
                    [pre] => Node Object
                        (
                            [key] => jzm
                            [value] => jzm
                            [pre] => 
                            [next] => Node Object
 *RECURSION*
                        )

                    [next] => Node Object
 *RECURSION*
                )

            [next] => 
        )

    [count] => 3
)
[why@whydeMacBook-Pro] ~/Desktop/php$

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章