成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之隊(duì)列

cnio / 2090人閱讀

摘要:環(huán)形隊(duì)列為充分利用向量空間,克服假溢出現(xiàn)象的方法是將向量空間想象為一個(gè)首尾相接的圓環(huán),并稱這種向量為循環(huán)向量。雙端隊(duì)列截止目前我們所實(shí)現(xiàn)的隊(duì)列都是在隊(duì)尾入隊(duì),隊(duì)首出隊(duì)的結(jié)構(gòu)。

什么是隊(duì)列

隊(duì)列是另外一種遵循先進(jìn)先出原則的線性數(shù)據(jù)結(jié)構(gòu)。隊(duì)列有兩端可供操作,一端出隊(duì),一端入隊(duì)。這個(gè)特點(diǎn)和棧不同,棧只有一端可以用來(lái)操作。入隊(duì)總是在后端,出隊(duì)在前端。

常見(jiàn)操作

enqueue -> 入隊(duì)

dequeue -> 出隊(duì)

peek -> 返回隊(duì)列前端元素

isEmpty -> 是否為空

PHP實(shí)現(xiàn)

首先我們定義一個(gè)QueueInterface。

interface QueueInterface
{
    public function enqueue(string $item);
    public function dequeue();
    public function isEmpty();
    public function peek();
}

來(lái)看基于數(shù)組的隊(duì)列實(shí)現(xiàn)

class ArrQueue implements QueueInterface
{
    private $queue;
    private $limit;

    public function __construct(int $limit = 0)
    {
       $this->limit = $limit;
       $this->queue = [];
    }

    public function isEmpty()
    {
        return empty($this->queue);
    }

    public function dequeue()
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("queue is empty");
        } else {
            array_shift($this->queue);
        }
    }

    public function enqueue(string $item)
    {
        if (count($this->queue) >= $this->limit) {
            throw new OverflowException("queue is full");
        } else {
            array_unshift($this->queue, $item);
        }
    }

    public function peek()
    {
        return current($this->queue);
    }
}

得益于PHP強(qiáng)大的array結(jié)構(gòu),我們輕而易舉的寫(xiě)出來(lái)了隊(duì)列的基本操作方法。果然世界上最好的語(yǔ)言名不虛傳。

可能機(jī)智的同學(xué)已經(jīng)猜到了,我之前已經(jīng)定義了一個(gè)隊(duì)列接口,那隊(duì)列的實(shí)現(xiàn)肯定不止只有上面一種哈。來(lái)看基于鏈表的實(shí)現(xiàn)。

class LinkedListQueue implements QueueInterface
{
    private $limit;
    private $queue;

    public function __construct(int $limit = 0)
    {
        $this->limit = $limit;
        $this->queue = new LinkedList();
    }

    public function isEmpty()
    {
        return $this->queue->getSize() == 0;
    }

    public function peek()
    {
        return $this->queue->getNthNode(0)->data;
    }

    public function enqueue(string $item)
    {
        if ($this->queue->getSize() < $this->limit) {
            $this->queue->insert($item);
        } else {
            throw new OverflowException("queue is full");
        }
    }

    public function dequeue()
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("queue is empty");
        } else {
            $lastItem = $this->peek();
            $this->queue->deleteFirst();

            return $lastItem;
        }
    }
}

里面涉及到了之前的鏈表實(shí)現(xiàn),不了解細(xì)節(jié)的同學(xué)可以去這里看看。

Spl中的隊(duì)列

強(qiáng)大的PHP已經(jīng)內(nèi)置了隊(duì)列實(shí)現(xiàn),可以使用的方法和上面我們自己實(shí)現(xiàn)的類似。

class SqlQueue
{
    private $splQueue;

    public function __construct()
    {
        $this->splQueue = new SplQueue();
    }

    public function enqueue(string $data = null)
    {
        $this->splQueue->enqueue($data);
    }

    public function dequeue()
    {
        return $this->splQueue->dequeue();
    }
}
優(yōu)先隊(duì)列

優(yōu)先隊(duì)列是一種特殊的隊(duì)列,入隊(duì)或者出隊(duì)的順序都是基于每個(gè)節(jié)點(diǎn)的權(quán)重。

順序序列

優(yōu)先隊(duì)列可以分為有序優(yōu)先隊(duì)列和無(wú)序優(yōu)先隊(duì)列。有序優(yōu)先隊(duì)列又有兩種情況,倒序或者順序。在順序序列中,我們可以迅速的找出最大或者最小優(yōu)先級(jí)別的節(jié)點(diǎn),復(fù)雜度是O(1)。但是插入的話會(huì)花費(fèi)掉更多的時(shí)間,因?yàn)槲覀円獧z查每一個(gè)節(jié)點(diǎn)的優(yōu)先級(jí)別然后插入到合適的位置。

無(wú)序序列

在無(wú)序序列中,在插入新節(jié)點(diǎn)的時(shí)候我們不需要根據(jù)他們的優(yōu)先級(jí)確定位置。入隊(duì)的時(shí)候像普通隊(duì)列一樣,插入到隊(duì)列的末尾。但是當(dāng)我們想移除優(yōu)先級(jí)最高的元素的時(shí)候,我們要掃描每一個(gè)節(jié)點(diǎn)來(lái)確定移除優(yōu)先級(jí)最高的那一個(gè)。接下來(lái)我們還是基于鏈表實(shí)現(xiàn)一個(gè)順序的優(yōu)先隊(duì)列。

class LinkedListPriorityQueue
{
    private $limit;
    private $queue;


    public function __construct(int $limit = 0)
    {
        $this->limit = $limit;
        $this->queue = new LinkedList();
    }

    public function enqueue(string $data = null, int $priority)
    {
        if ($this->queue->getSize() > $this->limit) {
            throw new OverflowException("Queue is full");
        } else {
            $this->queue->insert($data, $priority);
        }
    }

    public function dequeue(): string
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("Queue is empty");
        } else {
            $item = $this->peek();
            $this->queue->deleteFirst();

            return $item->data;
        }
    }

    public function peek()
    {
        return $this->queue->getNthNode(0);
    }

    public function isEmpty()
    {
        return $this->queue->getSize() === 0;
    }
}
環(huán)形隊(duì)列

為充分利用向量空間,克服"假溢出"現(xiàn)象的方法是:將向量空間想象為一個(gè)首尾相接的圓環(huán),并稱這種向量為循環(huán)向量。存儲(chǔ)在其中的隊(duì)列稱為循環(huán)隊(duì)列。環(huán)形隊(duì)列也是一種數(shù)組,只是它在邏輯上把數(shù)組的頭和尾相連,形成循環(huán)隊(duì)列,當(dāng)數(shù)組尾滿的時(shí)候,要判斷數(shù)組頭是否為空,不為空繼續(xù)存放數(shù)據(jù)。

class CircularQueue implements QueueInterface
{
    private $queue;
    private $limit;
    private $front = 0;
    private $rear = 0;

    public function __construct(int $limit = 0)
    {
        $this->limit = $limit;
        $this->queue = [];
    }

    public function isEmpty()
    {
        return $this->front === $this->rear;
    }

    public function isFull()
    {
        $diff = $this->rear - $this->front;

        if ($diff == -1 || $diff == ($this->limit - 1)) {
            return true;
        }

        return false;
    }

    public function peek()
    {
        return $this->queue[$this->front];
    }

    public function dequeue()
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("Queue is empty");
        }

        $item = $this->queue[$this->front];
        $this->queue[$this->front] = null;
        $this->front = ($this->front + 1) % $this->limit;

        return $item;
    }

    public function enqueue(string $item)
    {
        if ($this->isFull()) {
            throw new OverflowException("Queue is full");
        }

        $this->queue[$this->rear] = $item;
        $this->rear = ($this->rear + 1) % $this->limit;

    }
}
雙端隊(duì)列

截止目前我們所實(shí)現(xiàn)的隊(duì)列都是在隊(duì)尾(rear)入隊(duì),隊(duì)首(front) 出隊(duì)的結(jié)構(gòu)。在特殊的情況下,我們希望不論是隊(duì)首還是隊(duì)尾都可以入隊(duì)或者出隊(duì),這種結(jié)構(gòu)就叫做雙端隊(duì)列?;谖覀冎皩?shí)現(xiàn)的鏈表結(jié)構(gòu),我們可以輕而易舉的實(shí)現(xiàn)這樣的結(jié)構(gòu)。

class LinkedListDeQueue
{
    private $limit = 0;
    private $queue;

    public function __construct(int $limit = 0)
    {
        $this->limit = $limit;
        $this->queue = new DataStructureLinkedListLinkedList();
    }

    public function dequeueFromFront(): string 
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("Queue is empty");
        }

        $item = $this->queue->getNthNode(0);
        $this->queue->deleteFirst();

        return $item->data;
    }

    public function dequeueFromBack(): string 
    {
        if ($this->isEmpty()) {
            throw new UnderflowException("Queue is empty");
        }

        $item = $this->queue->getNthNode($this->queue->getSize() - 1);
        $this->queue->deleteLast();

        return $item->data;
    }

    public function isFull()
    {
        return $this->queue->getSize() >= $this->limit;
    }

    public function enqueueAtBack(string $data = null)
    {
        if ($this->isFull()) {
            throw new OverflowException("queue is full");
        }

        $this->queue->insert($data);
    }

    public function enqueueAtFront(string $data = null)
    {
        if ($this->isFull()) {
            throw new OverflowException("queue is full");
        }

        $this->queue->insertAtFirst($data);
    }

    public function isEmpty()
    {
        return $this->queue->getSize() === 0;
    }

    public function peekFront()
    {
        return $this->queue->getNthNode(0)->data;
    }

    public function peekBack()
    {
        return $this->queue->getNthNode($this->queue->getSize() - 1)->data;
    }
}

里面涉及到了之前的鏈表實(shí)現(xiàn),不了解細(xì)節(jié)的同學(xué)可以去這里看看。

總結(jié)

棧和隊(duì)列是我們最常用的數(shù)據(jù)結(jié)構(gòu),我們會(huì)在其他的復(fù)雜數(shù)據(jù)結(jié)構(gòu)中看到這兩種抽象數(shù)據(jù)類型的應(yīng)用。在下一章,我們繼續(xù)學(xué)習(xí)PHP數(shù)據(jù)結(jié)構(gòu)之遞歸,這是一種將復(fù)雜問(wèn)題簡(jiǎn)單化的常用思路。

專題系列

PHP基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)專題系列目錄地址:地址 主要使用PHP語(yǔ)法總結(jié)基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法。還有我們?nèi)粘HP開(kāi)發(fā)中容易忽略的基礎(chǔ)知識(shí)和現(xiàn)代PHP開(kāi)發(fā)中關(guān)于規(guī)范、部署、優(yōu)化的一些實(shí)戰(zhàn)性建議,同時(shí)還有對(duì)Javascript語(yǔ)言特點(diǎn)的深入研究。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/28865.html

相關(guān)文章

  • 實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)

    摘要:棧和隊(duì)列棧和隊(duì)列和之前講到的實(shí)戰(zhàn)數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之雙鏈表一樣都是線性結(jié)構(gòu)。來(lái)看基于數(shù)組的棧實(shí)現(xiàn)得益于強(qiáng)大的結(jié)構(gòu),我們輕而易舉的寫(xiě)出來(lái)了棧的基本操作方法。專題系列基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)專題系列目錄地址主要使用語(yǔ)法總結(jié)基礎(chǔ)的數(shù)據(jù)結(jié)構(gòu)和算法。 棧和隊(duì)列 棧和隊(duì)列和之前講到的實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之雙鏈表 一樣都是線性結(jié)構(gòu)。 棧有什么特點(diǎn) 棧遵循后進(jìn)先出的原則(LIFO)。這意味著棧只有一個(gè)出口用來(lái)壓入元素...

    banana_pi 評(píng)論0 收藏0
  • PHP基礎(chǔ)

    摘要:分別為適配器模式,裝飾器模式,代理模式,外觀模式,橋接模式,組合模式,享元模式。設(shè)計(jì)模式五適配器模式適配器模式將某個(gè)對(duì)象的接生成器和協(xié)程的實(shí)現(xiàn)在這篇文章中,作者針對(duì)那些比較難以理解的概念,以一個(gè)更為通俗的方式去講明白。。 PHP 源碼注解 PHP 的詳細(xì)源碼注解 PHP 字符串操作整理 一些有關(guān)字符串的常用操作。 Redis 常見(jiàn)七種使用場(chǎng)景 (PHP 實(shí)戰(zhàn)) 這篇文章主要介紹利用 R...

    HtmlCssJs 評(píng)論0 收藏0
  • PHPer書(shū)單

    摘要:想提升自己,還得多看書(shū)多看書(shū)多看書(shū)下面是我收集到的一些程序員應(yīng)該看得書(shū)單及在線教程,自己也沒(méi)有全部看完。共勉吧當(dāng)然,如果你有好的書(shū)想分享給大家的或者覺(jué)得書(shū)單不合理,可以去通過(guò)進(jìn)行提交。講師溫銘,軟件基金會(huì)主席,最佳實(shí)踐作者。 想提升自己,還得多看書(shū)!多看書(shū)!多看書(shū)!下面是我收集到的一些PHP程序員應(yīng)該看得書(shū)單及在線教程,自己也沒(méi)有全部看完。共勉吧!當(dāng)然,如果你有好的書(shū)想分享給大家的或者...

    jimhs 評(píng)論0 收藏0
  • PHP小知識(shí)點(diǎn)

    摘要:那些瑣碎的知識(shí)點(diǎn)作者記錄的的很奇特很難記的知識(shí)點(diǎn)。易錯(cuò)知識(shí)點(diǎn)整理注意和的區(qū)別中和都是輸出的作用,但是兩者之間還是有細(xì)微的差別。今天手頭不忙,總結(jié)一下,分享過(guò)程中掌握的知識(shí)點(diǎn)。 深入理解 PHP 之:Nginx 與 FPM 的工作機(jī)制 這篇文章從 Nginx 與 FPM 的工作機(jī)制出發(fā),探討配置背后的原理,讓我們真正理解 Nginx 與 PHP 是如何協(xié)同工作的。 PHP 那些瑣碎的知識(shí)...

    hover_lew 評(píng)論0 收藏0
  • 實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)雙鏈表

    摘要:什么是雙鏈表上一篇實(shí)戰(zhàn)數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之單鏈表說(shuō)到單鏈表由一個(gè)一個(gè)的作為節(jié)點(diǎn)的對(duì)象構(gòu)成的,每一個(gè)節(jié)點(diǎn)都有指向下一個(gè)節(jié)點(diǎn)的指針,最后一個(gè)節(jié)點(diǎn)的指針域指向空。 什么是雙鏈表? 上一篇實(shí)戰(zhàn)PHP數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)之單鏈表說(shuō)到 單鏈表由一個(gè)一個(gè)的作為節(jié)點(diǎn)的對(duì)象構(gòu)成的,每一個(gè)節(jié)點(diǎn)都有指向下一個(gè)節(jié)點(diǎn)的指針,最后一個(gè)節(jié)點(diǎn)的指針域指向空。每個(gè)節(jié)點(diǎn)可以存儲(chǔ)任何數(shù)據(jù)類型。 而雙鏈表每個(gè)節(jié)點(diǎn)有兩個(gè)指針域,分別指向前驅(qū)...

    Michael_Lin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<