为了账号安全,请及时绑定邮箱和手机立即绑定

实战PHP数据结构基础之栈

标签:
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('stack is overflow');
        }
    }    public function pop()
    {        if ($this->isEmpty()) {            throw new \UnderflowException('stack is empty');
        } 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('stack is empty');
        } 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('stack is overflow');
        }
    }

里面涉及到了之前的链表实现,不了解细节的同学可以去这里看看。有同学又问,那栈到底有什么用处?这个问题非常好,来看一个需求。

请实现一个数学表达式检查类,输入一个下面表达式,预期结果为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基础数据结构专题系列目录地址:地址 主要使用PHP语法总结基础的数据结构和算法。还有我们日常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特点的深入研究。



作者:肖潇_
链接:https://www.jianshu.com/p/012134ada560

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消