PHP SPL标准库-数据结构
SPL是用于解决典型问题的一组接口与类的集合。
双向链表
SplDoublyLinkedList
- SplStack
- SplQueue
双链表是一种重要的线性存储结构,对于双链表中的每个节点,不仅仅存储自己的信息,还要保存前驱和后继节点的地址。
PHP SPL中的SplDoublyLinkedList类提供了对双链表的操作。
双向链表概念:

- Bottom:最先添加到链表中的节点叫做 Bottom(底部),也称为头部(head)
- Top:最后添加到链表中的节点叫做top顶部,也称为尾部
- 链表指针:是一个当前关注的节点的标识,可以指向任意节点
- 当前指针:链表指针指向的节点称为当前节点
- 节点名称:可以在链表中唯一标识一个节点的名称,我们通常又称为节点的key或offset
- 节点数据:存放在链表中的应用数据,通常称为value
SplDoublyLinkedList类摘要如下:
SplDoublyLinkedList implements Iterator , ArrayAccess , Countable {
public __construct ( void )
public void add ( mixed $index , mixed $newval )
# 双链表的头部节点
public mixed top ( void )
# 双链表的尾部节点
public mixed bottom ( void )
# 双联表元素的个数
public int count ( void )
# 检测双链表是否为空
public bool isEmpty ( void )
# 当前节点索引
public mixed key ( void )
# 移到上条记录
public void prev ( void )
# 移到下条记录
public void next ( void )
# 当前记录
public mixed current ( void )
# 将指针指向迭代开始处
public void rewind ( void )
# 检查双链表是否还有节点
public bool valid ( void )
# 指定index处节点是否存在
public bool offsetExists ( mixed $index )
# 获取指定index处节点值
public mixed offsetGet ( mixed $index )
# 设置指定index处值
public void offsetSet ( mixed $index , mixed $newval )
# 删除指定index处节点
public void offsetUnset ( mixed $index )
# 从双链表的尾部弹出元素
public mixed pop ( void )
# 添加元素到双链表的尾部
public void push ( mixed $value )
# 序列化存储
public string serialize ( void )
# 反序列化
public void unserialize ( string $serialized )
# 设置迭代模式
public void setIteratorMode ( int $mode )
# 获取迭代模式SplDoublyLinkedList::IT_MODE_LIFO (Stack style) SplDoublyLinkedList::IT_MODE_FIFO (Queue style)
public int getIteratorMode ( void )
# 双链表的头部移除元素
public mixed shift ( void )
# 双链表的头部添加元素
public void unshift ( mixed $value )
}
使用:
$list = new SplDoublyLinkedList();
$list->push('a');
$list->push('b');
$list->push('c');
$list->push('d');
$list->unshift('top');
$list->shift();
// rewind操作用于把节点指针指向Bottom所在的节点
$list->rewind();
echo 'curren node:'.$list->current()."<br />"; // 获取当前节点 =============================
返回:
curren node:a
============================= $list->next(); // 指针指向下一个节点
echo 'next node:'.$list->current()."<br />"; =============================
返回:
next node:b
============================= $list->next();
$list->next();
$list->prev(); // 指针指向上一个节点
echo 'next node:'.$list->current()."<br />"; =============================
返回:
next node:c
============================= if($list->current())
echo 'current node is valid<br />';
else
echo 'current node is invalid<br />'; if($list->valid()) // 如果当前节点是有效节点,valid返回true
echo "valid list<br />";
else
echo "invalid list <br />"; =============================
返回:
current node is valid
valid list
============================= var_dump(array(
'pop' => $list->pop(),
'count' => $list->count(),
'isEmpty' => $list->isEmpty(),
'bottom' => $list->bottom(),
'top' => $list->top()
)); =============================
返回:
array (size=5)
'pop' => string 'd' (length=1)
'count' => int 3
'isEmpty' => boolean false
'bottom' => string 'a' (length=1)
'top' => string 'c' (length=1)
============================= $list->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO);
var_dump($list->getIteratorMode()); =============================
返回:
int 0
============================= for($list->rewind(); $list->valid(); $list->next()) {
echo $list->current().PHP_EOL;
} =============================
返回:
a b c
============================= var_dump($a = $list->serialize()); =============================
返回:
string 'i:0;:s:1:"a";:s:1:"b";:s:1:"c";' (length=31)
============================= $list->offsetSet(0,'new one');
$list->offsetUnset(0);
var_dump(array(
'offsetExists' => $list->offsetExists(4),
'offsetGet' => $list->offsetGet(0), ));
var_dump($list); =============================
array (size=2)
'offsetExists' => boolean false
'offsetGet' => string 'b' (length=1)
object(SplDoublyLinkedList)[1]
=============================
// 栈,后进先出
$stack = new SplStack(); // 继承自SplDoublyLinkedList类
$stack->push("a<br />");
$stack->push("b<br />"); echo $stack->pop();
echo $stack->pop(); =============================
返回:
b
a
============================= $stack->offsetSet(0,'B'); // 堆栈的offset=0是Top所在的位置,offset=1是Top位置节点靠近bottom位置的相邻节点,以此类推
$stack->rewind(); // 双向链表的rewind和堆栈的rewind相反,堆栈的rewind使得当前指针指向Top所在的位置,而双向链表调用之后指向bottom所在位置
echo 'current:'.$stack->current().'<br />'; =============================
返回:
current:B
============================= $stack->next(); // 堆栈的next操作使指针指向靠近bottom位置的下一个节点,而双向链表是靠近top的下一个节点
echo 'current:'.$stack->current().'<br />'; =============================
返回:
current:a
============================= // 队列,先进先出
$queue = new SplQueue(); // 继承自SplDoublyLinkedList类
$queue->enqueue("a<br />"); // 插入一个节点到队列里面的Top位置
$queue->enqueue("b<br />"); $queue->offsetSet(0,'A'); // 堆栈的offset=0是Top所在的位置,offset=1是Top位置节点靠近bottom位置的相邻节点,以此类推 echo $queue->dequeue();
echo $queue->dequeue(); =============================
返回:
Ab
=============================
堆
SplHeap
- SplMaxHeap
- SplMinHeap
堆(Heap)就是为了实现优先队列而设计的一种数据结构,它是通过构造二叉堆(二叉树的一种)实现。根节点最大的堆叫做最大堆或大根堆(SplMaxHeap),根节点最小的堆叫做最小堆或小根堆(SplMinHeap)。二叉堆还常用于排序(堆排序)。
SplHeap类摘要如下:
abstract SplHeap implements Iterator , Countable {
/* 方法 */
public __construct ( void )
abstract protected int compare ( mixed $value1 , mixed $value2 )
public int count ( void )
public mixed current ( void )
public mixed extract ( void )
public void insert ( mixed $value )
public bool isEmpty ( void )
public mixed key ( void )
public void next ( void )
public void recoverFromCorruption ( void )
public void rewind ( void )
public mixed top ( void )
public bool valid ( void )
}
这是一个抽象类,最大堆(SplMaxHeap)和最小堆(SplMinHeap)就是继承它实现的。最大堆和最小堆并没有额外的方法。
SplHeap简单使用:
class MySplHeap extends SplHeap{
// compare()方法用来比较两个元素的大小,绝对他们在堆中的位置
public function compare( $value1, $value2 ) {
return ( $value1 - $value2 );
}
}
$obj = new MySplHeap();
$obj->insert(0);
$obj->insert(1);
$obj->insert(2);
$obj->insert(3);
$obj->insert(4);
echo $obj->top(); // 4
echo $obj->count(); // 5
foreach ($obj as $item) {
echo $item."<br />";
}
队列
SplPriorityQueue
优先队列也是非常实用的一种数据结构,可以通过加权对值进行排序,由于排序在php内部实现,业务代码中将精简不少而且更高效。通过SplPriorityQueue::setExtractFlags(int $flag)设置提取方式可以提取数据(等同最大堆)、优先级、和两者都提取的方式。
SplPriorityQueue类摘要如下:
SplPriorityQueue implements Iterator , Countable {
/* 方法 */
public __construct ( void )
public int compare ( mixed $priority1 , mixed $priority2 )
public int count ( void )
public mixed current ( void )
public mixed extract ( void )
public void insert ( mixed $value , mixed $priority )
public bool isEmpty ( void )
public mixed key ( void )
public void next ( void )
public void recoverFromCorruption ( void )
public void rewind ( void )
public void setExtractFlags ( int $flags )
public mixed top ( void )
public bool valid ( void )
}
简单使用:
$pq = new SplPriorityQueue();
$pq->insert('a', 10);
$pq->insert('b', 1);
$pq->insert('c', 8);
echo $pq->count() .PHP_EOL; // 3
echo $pq->current() . PHP_EOL; // a
/**
* 设置元素出队模式
* SplPriorityQueue::EXTR_DATA 仅提取值
* SplPriorityQueue::EXTR_PRIORITY 仅提取优先级
* SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级
*/
$pq->setExtractFlags(SplPriorityQueue::EXTR_DATA);
while($pq->valid()) {
print_r($pq->current()); //a c b
$pq->next();
}
阵列
SplFixedArray
SplFixedArray主要是处理数组相关的主要功能,与普通php array不同的是,它是固定长度的,且以数字为键名的数组,优势就是比普通的数组处理更快。通常情况下SplFixedArray要比php array快上20%~30%,所以如果你是处理巨大数量的固定长度数组,还是强烈建议使用。
SplFixedArray类摘要如下:
SplFixedArray implements Iterator , ArrayAccess , Countable {
/* 方法 */
public __construct ([ int $size = 0 ] )
public int count ( void )
public mixed current ( void )
public static SplFixedArray fromArray ( array $array [, bool $save_indexes = true ] )
public int getSize ( void )
public int key ( void )
public void next ( void )
public bool offsetExists ( int $index )
public mixed offsetGet ( int $index )
public void offsetSet ( int $index , mixed $newval )
public void offsetUnset ( int $index )
public void rewind ( void )
public int setSize ( int $size )
public array toArray ( void )
public bool valid ( void )
public void __wakeup ( void )
}
简单使用:
$arr = new SplFixedArray(4);
$arr[0] = 'php';
$arr[1] = 1;
$arr[3] = 'python'; // 遍历, $arr[2] 为null
foreach($arr as $v) {
echo $v . PHP_EOL;
} // 获取数组长度
echo $arr->getSize(); //4 // 增加数组长度
$arr->setSize(5);
$arr[4] = 'new one'; // 捕获异常
try{
echo $arr[10];
} catch (RuntimeException $e) {
echo $e->getMessage();
}
映射
SplObjectStorage
用来存储一组对象的,特别是当你需要唯一标识对象的时候。
PHP SPL SplObjectStorage类实现了Countable、Iterator、Serializable、ArrayAccess四个接口。可实现统计、迭代、序列化、数组式访问等功能。
SplObjectStorage类摘要如下:
SplObjectStorage implements Countable , Iterator , Serializable , ArrayAccess {
/* 方法 */
public void addAll ( SplObjectStorage $storage )
public void attach ( object $object [, mixed $data = NULL ] )
public bool contains ( object $object )
public int count ( void )
public object current ( void )
public void detach ( object $object )
public string getHash ( object $object )
public mixed getInfo ( void )
public int key ( void )
public void next ( void )
public bool offsetExists ( object $object )
public mixed offsetGet ( object $object )
public void offsetSet ( object $object [, mixed $data = NULL ] )
public void offsetUnset ( object $object )
public void removeAll ( SplObjectStorage $storage )
public void removeAllExcept ( SplObjectStorage $storage )
public void rewind ( void )
public string serialize ( void )
public void setInfo ( mixed $data )
public void unserialize ( string $serialized )
public bool valid ( void )
}
简单使用:
class A {
public $i;
public function __construct($i) {
$this->i = $i;
}
}
$a1 = new A(1);
$a2 = new A(2);
$a3 = new A(3);
$a4 = new A(4);
$container = new SplObjectStorage();
// SplObjectStorage::attach 添加对象到Storage中
$container->attach($a1);
$container->attach($a2);
$container->attach($a3);
// SplObjectStorage::detach 将对象从Storage中移除
$container->detach($a2);
// SplObjectStorage::contains用于检查对象是否存在Storage中
var_dump($container->contains($a1)); # true
var_dump($container->contains($a4)); # false
// 遍历
$container->rewind();
while($container->valid()) {
var_dump($container->current());
$container->next();
}
PHP SPL标准库-数据结构的更多相关文章
- SPL标准库-数据结构
数据结构:栈 );] = ;] = ;var_dump($array); 来自为知笔记(Wiz)
- PHP SPL标准库之数据结构栈(SplStack)介绍(基础array已经可以解决很多问题了,现在开始解决问题)
PHP SPL标准库之数据结构栈(SplStack)介绍(基础array已经可以解决很多问题了,现在开始解决问题) 一.总结 SplStack就是继承双链表(SplDoublyLinkedList)实 ...
- php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)
php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便) 一.总结 直接看代码实例,特别方便易懂 thinkphp控制器利眠宁不支持(说明 ...
- PHP的SPL标准库里面的堆(SplHeap)怎么使用
PHP的SPL标准库里面的堆(SplHeap)怎么使用 一.总结 1.因为SplHeap是抽象类,所以要先继承,实现里面的抽象方法compare后,才能new对象使用. 二.PHP的SPL标准库里面的 ...
- PHP SPL标准库-接口
PHP SPL标准库有一下接口: Countable OuterIterator RecursiveIterator SeekableIterator SplObserver SplSubject A ...
- PHP 设计模式 笔记与总结(3)SPL 标准库
SPL 库的使用(PHP 标准库) 1. SplStack,SplQueue,SplHeap,SplFixedArray 等数据结构类 ① 栈(SplStack)(先进后出的数据结构) index.p ...
- 【SPL标准库专题(1)】 SPL简介
什么是SPL SPL是Standard PHP Library(PHP标准库)的缩写. 根据官方定义,它是"a collection of interfaces and classes th ...
- 3.Python3标准库--数据结构
(一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...
- PHP的SPL标准库
1,简介 SPL,全称 Standard PHP Library 中文是 标准PHP类库.是php内置的一些拓展类和拓展接口,其内容包含数据结构.迭代器.接口.异常.SPL函数,文件处理等内容.SPL ...
随机推荐
- 乔悟空-CTF-i春秋-Web-Backdoor
2020.09.05 每次遇到不会的,想两分钟就放弃了,直接奔wp,一看wp发现,wc,就这?我怎么没想到--心里想着下道题一定自己想,不看wp,然后周而复始
- JS 浏览器BOM
BOM:Browser Object Model 浏览器对象模型 2.组成: window :窗口对象 1.创建: 2.方法: *与弹出框有关 1.alert(); 弹出警告框 2.confirm() ...
- 第 8 篇:内容支持 Markdown 语法,接口返回包含解析后的 HTML
作者:HelloGitHub-追梦人物 在 Django博客教程(第二版) 中,我们给博客内容增加了 Markdown 的支持,博客详情接口应该返回解析后的 HTML 内容. 来回顾一下 Post 模 ...
- k8s滚动更新(六)
实践 滚动更新是一次只更新一小部分副本,成功后,再更新更多的副本,最终完成所有副本的更新.滚动更新的最大的好处是零停机,整个更新过程始终有副本在运行,从而保证了业务的连续性. 下面我们部署三副本应用, ...
- Guava Cache详解
适用性 缓存在很多场景下都是相当有用的.例如,计算或检索一个值的代价很高,并且对同样的输入需要不止一次获取值的时候,就应当考虑使用缓存 Guava Cache与ConcurrentMap很相似,但也不 ...
- Spring的三大核心接口——BeanFactory、ApplicationContext、WebApplicationContext
之前也在用这三个接口,但是对于他们的概念还是处于朦胧状态,同时,也不知道他们之间是一个什么关系,趁着现在有点时间总结一下吧,也需要对你有所帮助.一.BeanFactory 基本认识: ...
- Spring及tomcat初始化日志
Tomcat StandardContext初始化过程 //org.apache.catalina.core.StandardContext#startInternal // 子容器启动 for (C ...
- Mongodb PHP封装类
分享一个Mongodb PHP封装类 <?php /** * Mongodb 基本操作API,支持基本类似关系统型数据库的操作接口 * * @version 1.0 * [说明] * * 1:该 ...
- Centos-退出抽取设备-eject
eject 退出抽取设备,如光驱或磁带,如果设备已经挂载,则卸载设备 相关选项 -q 退出磁盘 -r 退出光盘 -d 显示默认设备
- mysql-15-view
#视图 /* 含义:虚拟表,和普通表一样使用.通过表动态生成的数据 只保存了sql逻辑,不保存查询结果 应用场景: 1.多个地方用到同样的查询结果 2.该查询结果使用的sql语句较为复杂 */ USE ...