AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
# SplPriorityQueue(堆之优先队列) ## [SplPriorityQueue:优先队列](https://www.php.net/manual/zh/class.splpriorityqueue.php#class.splpriorityqueue) > 优先队列也是非常实用的一种数据结构,可以通过加权对值进行排序,由于排序在php内部实现,业务代码中将精简不少而且更高效。通过SplPriorityQueue::setExtractFlags(int $flag)设置提取方式可以提取数据(等同最大堆)、优先级、和两者都提取的方式 > SplPriorityQueue类提供了使用最大堆实现的优先级队列的主要功能。 注意:具有相同优先级的元素的顺序未定义。它可能与插入顺序不同 > SplPriorityQueue是以`Heap`:`堆`数据结构实现的,默认为`MaxHeap`模式,即`priority`越大越优先出队,同时可以通过重写`compare`方法来使用`MinHeap`(优先级越低越优先出队,场景貌似很少吧) > 理解:当我们出队时会拿出`堆顶`的元素,此时`堆`的特性被破坏,`堆`会进行相应的调整至`稳定态`(`MaxHeap`or`MinHeap`),即会将`最后`一个元素替换到`堆顶`,然后进行`稳定态`验证,不符合堆特性则继续调整,或者我们就得到了一个`稳定态`的`堆`,所以当优先级相同,出队顺序并不会按照入队顺序 > SplPriorityQueue的入队方法和出队方法:insert和extract > extract 出队更为友好,即始终返回优先级最高的元素,优先级相投时会以堆调整的特性返回数据 > 注意,因为是`堆`实现,所以`rewind`方法是一个`no-op`没有什作用的操作,因为`头指针`始终指向`堆顶`,即`current`始终等于`top`,不像`List`只是游走指针,出队是会删除堆元素的,`extract`=`current + next`(current出队,从堆中删除) ``` <pre class="calibre10">``` abstract SplHeap implements <span class="token4">Iterator</span> <span class="token3">,</span> Countable <span class="token3">{</span> <span class="token">/* 方法 */</span> public __construct <span class="token3">(</span> void <span class="token3">)</span> abstract protected compare <span class="token3">(</span> mixed $value1 <span class="token3">,</span> mixed $value2 <span class="token3">)</span> <span class="token3">:</span> int <span class="token">//比较元素,以便在筛选时将它们正确地放在堆中,如果value1大于value2则为正整数,如果相等则为0,否则为负整数</span> public count <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> int <span class="token">//返回元素的个数 Countable </span> public current <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> mixed <span class="token">//返回当前记录节点索引的值 超出范围返回空 Iterator</span> public extract <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> mixed <span class="token">//从堆顶部提取节点并进行筛选</span> public insert <span class="token3">(</span> mixed $value <span class="token3">)</span> <span class="token3">:</span> void <span class="token">//通过筛选将一个元素插入堆中</span> public isCorrupted <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> bool <span class="token">//判断堆是否处于损坏状态</span> public isEmpty <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> bool <span class="token">//检查堆是否为空</span> public key <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> mixed <span class="token">//返回当前节点索引 Iterator</span> public next <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> void <span class="token">//移动到下一个节点 Iterator</span> public recoverFromCorruption <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> void <span class="token">//从损坏的状态恢复并允许堆上的进一步操作</span> public rewind <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> void <span class="token">//将指针指向迭代开始处 Iterator</span> public setExtractFlags <span class="token3">(</span> int $flags <span class="token3">)</span> <span class="token3">:</span> void <span class="token">//设置提取模式</span> public top <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> mixed <span class="token">//返回堆顶部的节点</span> public valid <span class="token3">(</span> void <span class="token3">)</span> <span class="token3">:</span> bool <span class="token">//检查堆是否还有节点 Iterator</span> <span class="token3">}</span> ``` ``` ## **例子:** ``` <pre class="calibre10">``` <span class="token1"><</span><span class="token1">?</span>php $objPQ <span class="token1">=</span> <span class="token5">new</span> <span class="token4">SplPriorityQueue</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'A'</span><span class="token3">,</span><span class="token6">3</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'B'</span><span class="token3">,</span><span class="token6">6</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'C'</span><span class="token3">,</span><span class="token6">1</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'D'</span><span class="token3">,</span><span class="token6">2</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">"COUNT->"</span><span class="token3">.</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">count</span><span class="token3">(</span><span class="token3">)</span><span class="token3">.</span><span class="token2">"<br>"</span><span class="token3">;</span> <span class="token">//mode of extraction </span> <span class="token">/** * 设置元素出队模式 * SplPriorityQueue::EXTR_DATA 仅提取值 * SplPriorityQueue::EXTR_PRIORITY 仅提取优先级 * SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级 */</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">setExtractFlags</span><span class="token3">(</span>SplPriorityQueue<span class="token3">:</span><span class="token3">:</span>EXTR_BOTH<span class="token3">)</span><span class="token3">;</span> <span class="token">//Go to TOP </span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">top</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//遍历:</span> <span class="token5">while</span><span class="token3">(</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">valid</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">{</span> <span class="token4">print_r</span><span class="token3">(</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">current</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">"<br>"</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">next</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> output<span class="token3">:</span> COUNT<span class="token1">-</span><span class="token1">></span><span class="token6">4</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> B <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">6</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> A <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">3</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> D <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">2</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> C <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">1</span> <span class="token3">)</span> <span class="token1">?</span><span class="token1">></span> ``` ``` ## **例子:** ``` <pre class="calibre17">``` <span class="token1"><</span><span class="token1">?</span>php class <span class="token4">PQtest</span> extends <span class="token4">SplPriorityQueue</span> <span class="token3">{</span> public <span class="token5">function</span> <span class="token4">compare</span><span class="token3">(</span>$priority1<span class="token3">,</span> $priority2<span class="token3">)</span> <span class="token3">{</span> <span class="token">//$priority1与优先级相同 3 6 ...</span> <span class="token5">if</span> <span class="token3">(</span>$priority1 <span class="token1">===</span> $priority2<span class="token3">)</span> <span class="token5">return</span> <span class="token6">0</span><span class="token3">;</span> <span class="token5">return</span> $priority1 <span class="token1"><</span> $priority2 <span class="token1">?</span> <span class="token1">-</span><span class="token6">1</span> <span class="token3">:</span> <span class="token6">1</span><span class="token3">;</span> <span class="token">// return $priority1 - $priority2;//高优先级优先</span> <span class="token">// return $priority2 - $priority1;//低优先级优先</span> <span class="token3">}</span> <span class="token3">}</span> $objPQ <span class="token1">=</span> <span class="token5">new</span> <span class="token4">PQtest</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token">//$objPQ->insert('值',优先级); </span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'A'</span><span class="token3">,</span><span class="token6">3</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'B'</span><span class="token3">,</span><span class="token6">6</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'C'</span><span class="token3">,</span><span class="token6">1</span><span class="token3">)</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">insert</span><span class="token3">(</span><span class="token2">'D'</span><span class="token3">,</span><span class="token6">2</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">"COUNT->"</span><span class="token3">.</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">count</span><span class="token3">(</span><span class="token3">)</span><span class="token3">.</span><span class="token2">"<br>"</span><span class="token3">;</span> <span class="token">/** * 设置元素出队模式 * SplPriorityQueue::EXTR_DATA 仅提取值 * SplPriorityQueue::EXTR_PRIORITY 仅提取优先级 * SplPriorityQueue::EXTR_BOTH 提取数组包含值和优先级 */</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">setExtractFlags</span><span class="token3">(</span>PQtest<span class="token3">:</span><span class="token3">:</span>EXTR_BOTH<span class="token3">)</span><span class="token3">;</span> <span class="token">//Go to TOP </span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">top</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token5">while</span><span class="token3">(</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">valid</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">{</span> <span class="token4">print_r</span><span class="token3">(</span>$objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">current</span><span class="token3">(</span><span class="token3">)</span><span class="token3">)</span><span class="token3">;</span> echo <span class="token2">"<br>"</span><span class="token3">;</span> $objPQ<span class="token1">-</span><span class="token1">></span><span class="token4">next</span><span class="token3">(</span><span class="token3">)</span><span class="token3">;</span> <span class="token3">}</span> <span class="token1">?</span><span class="token1">></span> output<span class="token3">:</span> COUNT<span class="token1">-</span><span class="token1">></span><span class="token6">4</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> B <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">6</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> A <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">3</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> D <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">2</span> <span class="token3">)</span> Array <span class="token3">(</span> <span class="token3">[</span>data<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> C <span class="token3">[</span>priority<span class="token3">]</span> <span class="token1">=</span><span class="token1">></span> <span class="token6">1</span> <span class="token3">)</span> ``` ```