php splpriorityqueue,SplPriorityQueue(堆之优先队列)

## [SplPriorityQueue:优先队列](https://www.php.net/manual/zh/class.splpriorityqueue.php#class.splpriorityqueue)

>[info]优先队列也是非常实用的一种数据结构,可以通过加权对值进行排序,由于排序在php内部实现,业务代码中将精简不少而且更高效。通过SplPriorityQueue::setExtractFlags(int $flag)设置提取方式可以提取数据(等同最大堆)、优先级、和两者都提取的方式

SplPriorityQueue类提供了使用最大堆实现的优先级队列的主要功能。 注意:具有相同优先级的元素的顺序未定义。它可能与插入顺序不同

SplPriorityQueue是以`Heap`:`堆`数据结构实现的,默认为`MaxHeap`模式,即`priority`越大越优先出队,同时可以通过重写`compare`方法来使用`MinHeap`(优先级越低越优先出队,场景貌似很少吧)

理解:当我们出队时会拿出`堆顶`的元素,此时`堆`的特性被破坏,`堆`会进行相应的调整至`稳定态`(`MaxHeap`or`MinHeap`),即会将`最后`一个元素替换到`堆顶`,然后进行`稳定态`验证,不符合堆特性则继续调整,或者我们就得到了一个`稳定态`的`堆`,所以当优先级相同,出队顺序并不会按照入队顺序

SplPriorityQueue的入队方法和出队方法:insert和extract

extract 出队更为友好,即始终返回优先级最高的元素,优先级相投时会以堆调整的特性返回数据

>[danger] 注意,因为是`堆`实现,所以`rewind`方法是一个`no-op`没有什作用的操作,因为`头指针`始终指向`堆顶`,即`current`始终等于`top`,不像`List`只是游走指针,出队是会删除堆元素的,`extract`\=`current + next`(current出队,从堆中删除)

```

abstract SplHeap implements Iterator , Countable {

/* 方法 */

public __construct ( void )

abstract protected compare ( mixed $value1 , mixed $value2 ) : int //比较元素,以便在筛选时将它们正确地放在堆中,如果value1大于value2则为正整数,如果相等则为0,否则为负整数

public count ( void ) : int //返回元素的个数 Countable

public current ( void ) : mixed //返回当前记录节点索引的值 超出范围返回空 Iterator

public extract ( void ) : mixed //从堆顶部提取节点并进行筛选

public insert ( mixed $value ) : void //通过筛选将一个元素插入堆中

public isCorrupted ( void ) : bool //判断堆是否处于损坏状态

public isEmpty ( void ) : bool //检查堆是否为空

public key ( void ) : mixed //返回当前节点索引 Iterator

public next ( void ) : void //移动到下一个节点 Iterator

public recoverFromCorruption ( void ) : void //从损坏的状态恢复并允许堆上的进一步操作

public rewind ( void ) : void //将指针指向迭代开始处 Iterator

public setExtractFlags ( int $flags ) : void //设置提取模式

public top ( void ) : mixed //返回堆顶部的节点

public valid ( void ) : bool //检查堆是否还有节点 Iterator

}

```

## **例子:**

```

$objPQ = new SplPriorityQueue();

$objPQ->insert('A',3);

$objPQ->insert('B',6);

$objPQ->insert('C',1);

$objPQ->insert('D',2);

echo "COUNT->".$objPQ->count()."
";

//mode of extraction

/**

* 设置元素出队模式

* SplPriorityQueue::EXTR_DATA 仅提取值

* SplPriorityQueue::EXTR_PRIORITY 仅提取优先级

* SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级

*/

$objPQ->setExtractFlags(SplPriorityQueue::EXTR_BOTH);

//Go to TOP

$objPQ->top();

//遍历:

while($objPQ->valid()){

print_r($objPQ->current());

echo "
";

$objPQ->next();

}

output:

COUNT->4

Array ( [data] => B [priority] => 6 )

Array ( [data] => A [priority] => 3 )

Array ( [data] => D [priority] => 2 )

Array ( [data] => C [priority] => 1 )

?>

```

## **例子:**

```

class PQtest extends SplPriorityQueue

{

public function compare($priority1, $priority2)

{

//$priority1与优先级相同 3 6 ...

if ($priority1 === $priority2) return 0;

return $priority1 < $priority2 ? -1 : 1;

// return $priority1 - $priority2;//高优先级优先

// return $priority2 - $priority1;//低优先级优先

}

}

$objPQ = new PQtest();

//$objPQ->insert('值',优先级);

$objPQ->insert('A',3);

$objPQ->insert('B',6);

$objPQ->insert('C',1);

$objPQ->insert('D',2);

echo "COUNT->".$objPQ->count()."
";

/**

* 设置元素出队模式

* SplPriorityQueue::EXTR_DATA 仅提取值

* SplPriorityQueue::EXTR_PRIORITY 仅提取优先级

* SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级

*/

$objPQ->setExtractFlags(PQtest::EXTR_BOTH);

//Go to TOP

$objPQ->top();

while($objPQ->valid()){

print_r($objPQ->current());

echo "
";

$objPQ->next();

}

?>

output:

COUNT->4

Array ( [data] => B [priority] => 6 )

Array ( [data] => A [priority] => 3 )

Array ( [data] => D [priority] => 2 )

Array ( [data] => C [priority] => 1 )

```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值