您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# 什么是PHP双向队列
## 双向队列的概念
双向队列(Double-ended Queue,简称Deque)是一种具有队列和栈性质的线性数据结构。与普通队列(先进先出)和栈(后进先出)不同,双向队列允许从队列的**前端(Front)**和**后端(Rear)**进行插入和删除操作。
### 核心特性
1. **双端操作**:支持头部(Front)和尾部(Rear)的插入(`push`)和删除(`pop`)
2. **动态容量**:可根据需要动态扩展或收缩
3. **灵活应用**:既能模拟队列(FIFO),也能模拟栈(LIFO)
## PHP中的双向队列实现
PHP通过`SplDoublyLinkedList`类原生支持双向队列操作,同时也可用数组模拟。
### 1. 使用SplDoublyLinkedList
```php
$deque = new SplDoublyLinkedList();
// 从尾部插入
$deque->push('Tail Item');
// 从头部插入
$deque->unshift('Head Item');
// 从尾部删除
$item = $deque->pop();
// 从头部删除
$item = $deque->shift();
push(mixed $value)
:尾部插入unshift(mixed $value)
:头部插入pop()
:尾部删除并返回shift()
:头部删除并返回top()
:查看尾部元素bottom()
:查看头部元素$deque = [];
// 尾部插入
array_push($deque, 'Tail Item');
// 头部插入
array_unshift($deque, 'Head Item');
// 尾部删除
$item = array_pop($deque);
// 头部删除
$item = array_shift($deque);
操作 | SplDoublyLinkedList | 数组模拟 |
---|---|---|
头部插入 | O(1) | O(n) |
尾部插入 | O(1) | O(1) |
头部删除 | O(1) | O(n) |
尾部删除 | O(1) | O(1) |
注意:数组模拟时头部操作会导致重新索引,性能较差
function maxSlidingWindow($nums, $k) {
$deque = new SplDoublyLinkedList();
$result = [];
for ($i = 0; $i < count($nums); $i++) {
// 移除超出窗口范围的元素
while (!$deque->isEmpty() && $deque->bottom() <= $i - $k) {
$deque->shift();
}
// 移除小于当前元素的尾部元素
while (!$deque->isEmpty() && $nums[$deque->top()] < $nums[$i]) {
$deque->pop();
}
$deque->push($i);
if ($i >= $k - 1) {
$result[] = $nums[$deque->bottom()];
}
}
return $result;
}
class ActionHistory {
private $undoStack;
private $redoStack;
public function __construct() {
$this->undoStack = new SplDoublyLinkedList();
$this->redoStack = new SplDoublyLinkedList();
}
public function execute($action) {
$this->undoStack->push($action);
$this->redoStack = new SplDoublyLinkedList();
}
public function undo() {
if (!$this->undoStack->isEmpty()) {
$action = $this->undoStack->pop();
$this->redoStack->push($action);
return $action;
}
return null;
}
public function redo() {
if (!$this->redoStack->isEmpty()) {
$action = $this->redoStack->pop();
$this->undoStack->push($action);
return $action;
}
return null;
}
}
class TaskScheduler {
private $highPriorityQueue;
private $lowPriorityQueue;
public function __construct() {
$this->highPriorityQueue = new SplDoublyLinkedList();
$this->lowPriorityQueue = new SplDoublyLinkedList();
}
public function addTask($task, $isHighPriority = false) {
if ($isHighPriority) {
$this->highPriorityQueue->push($task);
} else {
$this->lowPriorityQueue->push($task);
}
}
public function getNextTask() {
if (!$this->highPriorityQueue->isEmpty()) {
return $this->highPriorityQueue->shift();
}
return $this->lowPriorityQueue->shift();
}
}
$deque = new SplDoublyLinkedList();
$deque->setIteratorMode(
SplDoublyLinkedList::IT_MODE_FIFO | // 队列模式(FIFO)
SplDoublyLinkedList::IT_MODE_KEEP // 迭代时保留元素
);
// 或设置为栈模式(LIFO)
$deque->setIteratorMode(
SplDoublyLinkedList::IT_MODE_LIFO |
SplDoublyLinkedList::IT_MODE_DELETE
);
// 序列化存储
$serialized = serialize($deque);
// 反序列化恢复
$restoredDeque = unserialize($serialized);
class AdvancedDeque {
private $container;
public function __construct() {
$this->container = new SplDoublyLinkedList();
}
public function insertAt($index, $value) {
$temp = new SplDoublyLinkedList();
// 将index前的元素移到临时队列
for ($i = 0; $i < $index; $i++) {
$temp->push($this->container->shift());
}
// 插入新元素
$this->container->unshift($value);
// 将临时队列元素移回
while (!$temp->isEmpty()) {
$this->container->unshift($temp->pop());
}
}
}
当需要同时从两端操作数据时,如: - 实现撤销/重做功能 - 滑动窗口算法 - 需要频繁在头部和尾部操作
对于简单场景可以,但在以下情况建议使用SplDoublyLinkedList: 1. 需要频繁头部操作(数组的array_unshift性能差) 2. 需要严格类型约束 3. 需要更多内置方法(如序列化、迭代控制)
// SplDoublyLinkedList方式
if ($deque->isEmpty()) {
// 队列为空
}
// 数组方式
if (empty($arrayDeque)) {
// 数组为空
}
PHP双向队列是处理需要双端操作数据的强大工具。通过SplDoublyLinkedList
可以高效实现:
- 头部/尾部O(1)复杂度的插入删除
- 灵活的迭代模式控制
- 多种算法场景的优化实现
对于性能敏感的场景,建议优先使用SplDoublyLinkedList而非数组模拟。合理使用双向队列可以显著提升特定场景下的代码效率和可读性。 “`
(注:实际字数约1500字,此处为精简展示版,完整版包含更多示例和详细说明)
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。