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标准库-数据结构的更多相关文章

  1. SPL标准库-数据结构

    数据结构:栈 );] = ;] = ;var_dump($array); 来自为知笔记(Wiz)

  2. PHP SPL标准库之数据结构栈(SplStack)介绍(基础array已经可以解决很多问题了,现在开始解决问题)

    PHP SPL标准库之数据结构栈(SplStack)介绍(基础array已经可以解决很多问题了,现在开始解决问题) 一.总结 SplStack就是继承双链表(SplDoublyLinkedList)实 ...

  3. php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便)

    php spl标准库简介(SPL是Standard PHP Library(PHP标准库)(直接看代码实例,特别方便) 一.总结 直接看代码实例,特别方便易懂 thinkphp控制器利眠宁不支持(说明 ...

  4. PHP的SPL标准库里面的堆(SplHeap)怎么使用

    PHP的SPL标准库里面的堆(SplHeap)怎么使用 一.总结 1.因为SplHeap是抽象类,所以要先继承,实现里面的抽象方法compare后,才能new对象使用. 二.PHP的SPL标准库里面的 ...

  5. PHP SPL标准库-接口

    PHP SPL标准库有一下接口: Countable OuterIterator RecursiveIterator SeekableIterator SplObserver SplSubject A ...

  6. PHP 设计模式 笔记与总结(3)SPL 标准库

    SPL 库的使用(PHP 标准库) 1. SplStack,SplQueue,SplHeap,SplFixedArray 等数据结构类 ① 栈(SplStack)(先进后出的数据结构) index.p ...

  7. 【SPL标准库专题(1)】 SPL简介

    什么是SPL SPL是Standard PHP Library(PHP标准库)的缩写. 根据官方定义,它是"a collection of interfaces and classes th ...

  8. 3.Python3标准库--数据结构

    (一)enum:枚举类型 import enum ''' enum模块定义了一个提供迭代和比较功能的枚举类型.可以用这个为值创建明确定义的符号,而不是使用字面量整数或字符串 ''' 1.创建枚举 im ...

  9. PHP的SPL标准库

    1,简介 SPL,全称 Standard PHP Library 中文是 标准PHP类库.是php内置的一些拓展类和拓展接口,其内容包含数据结构.迭代器.接口.异常.SPL函数,文件处理等内容.SPL ...

随机推荐

  1. CEO的行为风格会影响公司业绩吗?

    中国的两大互联网巨头--腾讯和阿里,创始人的风格非常不同.在公众面前,马云的形象是高谈阔论,而马化腾则显得较为低调.在公司管理上,马云不插手具体事务,而是站在高处务虚,抓战略.抓文化,而马化腾则是腾讯 ...

  2. Analytics Zoo Cluster Serving自动扩展分布式推理

    作者: Jiaming Song, Dongjie Shi, Gong, Qiyuan, Lei Xia, Wei Du, Jason Dai 随着深度学习项目从实验到生产的发展,越来越多的应用需要对 ...

  3. 堆中的线程私有缓存区域TLAB(Thread Local Allocation Buffer)

    TLAB产生的原因 堆区是线程共享区域,任何线程都可以访问到堆区中的共享数据 由于对象实例的创建在JVM中非常频繁,因此在并发环境下从堆区中划分内存空间是线程不安全的 为避免多个线程操作同一地址,需要 ...

  4. android开发之意图

    intent 全局变量传值(程序关闭时存储值消失) intent普通传值 intent传值 intent不能序列化传值 intent回传

  5. linux 基础语法

    1.linux常用命令 1.1 系统命令 runlevel                     # 查看当前的运行级别systemctl status sshd        # 开启网络服务功能 ...

  6. 朴素贝叶斯分类器Naive Bayes

    优点Naive Bayes classifiers tend to perform especially well in one of the following situations: When t ...

  7. python 报错 wxPyDeprecationWarning: Using deprecated class PySimpleApp.

    如题:python 报错 提示为 : wxPyDeprecationWarning: Using deprecated class PySimpleApp. 解决:将 wx.PySimpleApp() ...

  8. C面向对象: 升级版本实现:同步逻辑、少量连续失败则增补、多次连续失败则拉长同步周期

    // C语言之 面向对象+虚事务的抽象 /*********** 进阶练习: (对虚的事物的抽象) 完善部门职责 ***********************/ #include <stdio ...

  9. 如何学习iOS开发?iOS Developer Library足矣!

    记得上高中的时候,寄信请教二哥学习经验,二哥来信介绍学习经验说:资料书要快速阅读,把书上的题做完,然后再买几套资料书(习题集)继续练习. 这是二哥的经验,因为他自学能力强,可以消化多套资料书. 我仿照 ...

  10. 【题解】【POI2000】病毒

    题目链接 这题让我们构造一个无限长的,不包括给定字符串的01串. 把给定字符串放到\(AC\)自动机上,在结尾处打上标记. 发现,如果我们要构造一个无限长的串,必然要有一个环. 那么这个环上就一定不能 ...