首頁  >  文章  >  後端開發  >  PHP資料結構基礎之棧

PHP資料結構基礎之棧

不言
不言原創
2018-07-06 17:06:411497瀏覽

這篇文章主要介紹了關於PHP資料結構基礎之棧,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

堆疊和佇列

棧和佇列和之前講到的實戰PHP資料結構基礎之雙鍊錶一樣都是線性結構。

堆疊有什麼特點

堆疊遵循後進先出的原則(LIFO)。這意味著棧只有一個出口用來壓入元素和彈出元素,當我們執行壓入或彈出操作的時候要注意棧是否已滿或棧是否是空的。

常見運算

還是廢話不多說,直接來看我們對堆疊執行的常用操作。

  • push

  • pop

  • top

  • isEmpty

  • ...

PHP實作

首先我們定義一個StackInterface。

interface StackInterface
{
    public function push(string $item);
    public function pop();
    public function top();
    public function isEmpty();
}

來看基於陣列的堆疊實作

class ArrStack implements StackInterface
{
    private $stack;
    private $limit;

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

    public function __get($val)
    {
        return $this->$val;
    }

    public function push(string $data = null)
    {
        if (count($this->stack) < $this->limit) {
            array_push($this->stack, $data);
        } else {
            throw new \OverflowException(&#39;stack is overflow&#39;);
        }
    }

    public function pop()
    {
        if ($this->isEmpty()) {
            throw new \UnderflowException(&#39;stack is empty&#39;);
        } else {
            return array_pop($this->stack);
        }
    }

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

    public function top()
    {
        return end($this->stack);
    }

得益於PHP強大的array結構,我們輕而易舉的寫出來了堆疊的基本操作方法。果然全世界最好的語言名不虛傳。

那有同學說了,你說堆疊和之前的鍊錶都是線性結構,那可不可以直接使用鍊錶實作堆疊呢?這個問題非常犀利啊,答案是可以的。

可能機智的同學已經猜到了,我之前已經定義了一個棧接口,那棧的實現肯定不止只有上面一種哈。來看基於鍊錶的實作。

class LinkedListStack implements StackInterface
{
    private $stack;
    private $limit;

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

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

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

    public function pop()
    {
        if ($this->isEmpty()) {
            throw new \UnderflowException(&#39;stack is empty&#39;);
        } else {
            $lastItem = $this->top();
            $this->stack->deleteLast();

            return $lastItem;
        }
    }

    public function push(string $item)
    {
        if ($this->stack->getSize() < $this->limit) {
            $this->stack->insert($item);
        } else {
            throw new \OverflowException(&#39;stack is overflow&#39;);
        }
    }

裡面涉及到了之前的鍊錶實現,不了解細節的同學可以去這裡看看。有同學又問,那棧到底有什麼用?這個問題非常好,來看一個需求。

請實作一個數學表達式檢查類,輸入一個下面表達式,預期結果為true。

"8 * (9 -2) + { (4 * 5) / ( 2 * 2) }

下面的為false。

"5 * 8 * 9 / ( 3 * 2 ) )"

下面的也為false。

"[{ (2 * 7) + ( 15 - 3) ]"

自己想一下,再往下看實作。

class ExpressionChecker
{
    //$expressions[] = "8 * (9 -2) + { (4 * 5) / ( 2 * 2) }";
    //$expressions[] = "5 * 8 * 9 / ( 3 * 2 ) )";
    //$expressions[] = "[{ (2 * 7) + ( 15 - 3) ]";

    public function check(string $expression): bool
    {
        $stack = new \SplStack();

        foreach (str_split($expression) as $item) {
            switch ($item) {
                case '{':
                case '[':
                case '(':
                    $stack->push($item);
                    break;

                case '}':
                case ']':
                case ')':
                    if ($stack->isEmpty()) return false;

                    $last = $stack->pop();

                    if (
                        $item == '{' && $last != '}' ||
                        $item == '(' && $last != ')' ||
                        $item == '[' && $last != ']'
                    )
                        return false;

                    break;
            }
        }

        if ($stack->isEmpty()) {
            return true;
        }

        return false;
    }
}

專題系列

PHP基礎資料結構專題系列目錄位址:https://github.com/... 主要使用PHP語法總結基礎的資料結構與演算法。還有我們日常PHP開發中容易忽略的基礎知識和現代PHP開發中關於規格、部署、最佳化的一些實戰性建議,同時還有對Javascript語言特徵的深入研究。

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

php redis的加鎖與解鎖

#PHP操作Beanstalkd的方法及參數註解

以上是PHP資料結構基礎之棧的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn