栈和队列和以前讲到的实战PHP数据结构基础之双链表 同样都是线性结构。git
栈遵循后进先出的原则(LIFO)。这意味着栈只有一个出口用来压入元素和弹出元素,当咱们执行压入或者弹出操做的时候要注意栈是否已满或者栈是不是空的。github
仍是废话很少说,直接来看咱们对栈执行的经常使用操做。web
首先咱们定义一个StackInterface。算法
interface StackInterface {
public function push(string $item);
public function pop();
public function top();
public function isEmpty();
}
复制代码
来看基于数组的栈实现express
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结构,咱们垂手可得的写出来了栈的基本操做方法。果真世界上最好的语言名不虚传。数组
那有同窗说了,你说栈和以前的链表都是线性结构,那可不能够直接使用链表实现栈呢?这个问题很是犀利啊,答案是能够的。bash
可能机智的同窗已经猜到了,我以前已经定义了一个栈接口,那栈的实现确定不止只有上面一种哈。来看基于链表的实现。数据结构
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基础数据结构专题系列目录地址:github.com/... 主要使用PHP语法总结基础的数据结构和算法。还有咱们平常PHP开发中容易忽略的基础知识和现代PHP开发中关于规范、部署、优化的一些实战性建议,同时还有对Javascript语言特色的深刻研究。