SplQueue类提供使用双向链表实现的队列的主要功能。
SplQueue从SplDoublyLinkedList继承
1、有模式的两个正交组可以设置:
1.迭代的方向
SplDoublyLinkedList::IT_MODE_LIFO(堆叠型)
SplDoublyLinkedList::IT_MODE_FIFO(队列分格)
2.迭代器的行为
SplDoublyLinkedList::IT_MODE_DELETE(迭代删除)
SplDoublyLinkedList::IT_MODE_KEEP(迭代遍历)
默认的模式为:SplDoublyLinkedList::IT_MODE_FIFO|SplDoublyLinkedList::IT_MODE_KEEP;
在迭代的方向中,堆叠性的方向是从链表的top到bottom(后进先出),而队列风格则相反(先进先出)。
在迭代的行为中,迭代删除会将链表中的元素迭代删除,而迭代遍历仅会将链表中的元素遍历一遍。
2、 SplQueue的方法
__construct — 使用双向链表创建新队列
dequeue — 从队列中删除节点
enqueue — 向队列中添加一个元素
setIteratorMode — 设置迭代的模式
3、 从SplDoublyLinkedList继承的方法
add ( mixed $index , mixed $newval ) # 在指定的索引处添加新节点
bottom ( void ) # 获取双链表的头部(底部)的节点(the first node)(不弹出)
top ( void ) # 获取双向链表的尾部(顶部)的节点(the last node)(不弹出)
count ( void ) # 返回双向链表内容的数量
current ( void ) # 返回当前节点的值(the current node)
getIteratorMode ( void ) # 返回迭代模式的值
isEmpty ( void ) # 检查双链表是否为空
key ( void ) # 返回当前节点的索引值
next ( void ) # 移动迭代器到下一个节点
offsetExists ( mixed $index ) # 返回请求的索引是否存在
offsetGet ( mixed $index ) # 返回指定索引处的值
offsetSet ( mixed $index , mixed $newval ) # 设置指定索引处的值为新值
offsetUnset ( mixed $index ) # 删除指定索引处的节点(双链表会重排)
prev ( void ) # 移动到上一个节点
push ( mixed $value ) # 在双链表的尾部(顶部)追加节点
rewind ( void ) # 重置迭代器到开始的位置
serialize ( void ) # 返回序列化后的链表,形如i:0;:i:4;:i:6;:i:7;:i:8;
setIteratorMode ( int $mode ) # 设置遍历模式
pop ( void ) # 弹出双链表的尾部(顶部)的节点(the last node)
unserialize ( string $serialized ) # 反序列化存储(没太搞懂,根据测试结果,反序列化后好像是把原来序列化后的string反序列化后又追加到了该链表中了)
shift ( void ) # 弹出双链表的头部(底部)的节点(the first node)
unshift ( mixed $value ) # 在双链表的头部(底部)追加节点
valid ( void ) # 检查双链表是否包含更多的节点
4、演示
4.1 简单的使用方式
$link = new SplDoublyLinkedList();
$link->push(4);
$link->push(5);
$link->push(6);
$link->push(7);
$link->push(8);
$link->push(9);
echo "双链表的迭代模式为:\n";
$link->setIteratorMode(SplDoublyLinkedList::IT_MODE_FIFO | SplDoublyLinkedList::IT_MODE_KEEP);
$mode = $link->getIteratorMode();
var_dump($mode);
echo "双链表为:\n";
var_dump($link);
$node = $link->pop(); //弹出,改变链表
echo "pop弹出尾部的节点为:\n";
var_dump($node);
$link->offsetUnset(1);
echo "删除索引为1的位置的node节点后的双链表为: \n";
var_dump($link); //链表重排
echo "当前的节点在:\n";
$link->rewind();
$current = $link->current();
var_dump($current);
echo "下一个节点在:\n";
$link->next();
$next = $link->current();
var_dump($next);
echo "下一个的上一个的节点在:\n";
$link->prev();
$last = $link->current();
var_dump($last);
$shift = $link->shift();
echo "shift值为\n";
var_dump($shift);
var_dump($link); //弹出,改变链表
$bottom = $link->bottom();
echo "bottom值为\n";
var_dump($bottom);
var_dump($link); //获取,未改变链表
$top = $link->top();
echo "top值为:\n";
var_dump($top);
var_dump($link); //获取,未改变链表
echo "在双链表的底部追加节点\n";;
$link->unshift("233333");
var_dump($link); //追加,改变链表
echo "在双链表的顶部追加节点\n";
$link->push("11111");
var_dump($link); //追加,改变链表
4.2 理解SplQueue的简单使用
<?php
class Test {
public static function foo() {
echo 'Test::foo() called'.PHP_EOL;
}
public static function bar() {
echo 'Test::bar() called'.PHP_EOL;
}
public static function msg($msg) {
echo "$msg".PHP_EOL;
}
}
$queue = new SplQueue();
//SplQueue遍历方向从始至终都是FIFO无需像SplDoublyLinkedList进行设置,只需设置迭代完成后是否移除元素
$queue->setIteratorMode(SplQueue::IT_MODE_DELETE);
//追加元素到队列中
$queue->enqueue(array("Test", "foo"));
$queue->enqueue(array("Test", "bar"));
$queue->enqueue(array("Test", "msg", "Hi there!"));
var_dump($queue);
foreach ($queue as $task) {
if (count($task) > 2) {
list($class, $method, $args) = $task;
echo "class: ".$class."\n";
echo "method: ".$method."\n";
echo "args: ".$args."\n";
$class::$method($args);
} else {
var_dump($task);
list($class, $method) = $task;
echo "class: ".$class."\n";
echo "method: ".$method."\n";
$class::$method();
}
}