PHP プライオリティ キューの概要 (コード付き)

不言
リリース: 2023-04-05 17:54:02
転載
3253 人が閲覧しました

この記事では、PHP プライオリティ キューの概要 (コード付き) を紹介します。一定の参考価値があります。必要な友人は参照してください。お役に立てば幸いです。

PHP の SPL ライブラリには SplPriorityQueue 優先キューが組み込まれており、ヒープ データ構造で実装されています。デフォルトは MaxHeap モードです。つまり、優先度が大きいほどキューに優先順位が与えられます。同時に、compareメソッドを書き換えることでMinHeapを利用することも可能です(優先度が低いほどデキューが優先され、シナリオは非常に少ないようです)。

SplPriorityQueue

ヒープの特性

ここで注意して理解する必要があります: SplPriorityQueue はヒープ データ構造で実装されています。デキューするときは、次の場所にある要素を取り出します。このとき、ヒープの特性は破壊され、ヒープは安定した状態 (MaxHeap または MinHeap) に応じて調整されます。つまり、最後の要素がヒープの先頭に置き換えられます。ヒープの特性を満たしていない場合は、調整を続けるか、安定したヒープが得られるため、優先度が同じ場合、デキューの順序はエンキューに続きません。注文。

ソースコード例:

<?php
$splPriorityQueue = new \SplPriorityQueue();
// 设定返回数据的meta信息
// \SplPriorityQueue::EXTR_DATA 默认 只返回数
// \SplPriorityQueue::EXTR_PRIORITY 只返回优先级
// \SplPriorityQueue::EXTR_BOTH 返回数据和优先级
// $splPriorityQueue->setExtractFlags(\SplPriorityQueue::EXTR_DATA);
$splPriorityQueue->insert("task1", 1);
$splPriorityQueue->insert("task2", 1);
$splPriorityQueue->insert("task3", 1);
$splPriorityQueue->insert("task4", 1);
$splPriorityQueue->insert("task5", 1);

echo $splPriorityQueue->extract() . PHP_EOL;
echo $splPriorityQueue->extract() . PHP_EOL;
echo $splPriorityQueue->extract() . PHP_EOL;
echo $splPriorityQueue->extract() . PHP_EOL;
echo $splPriorityQueue->extract() . PHP_EOL;

//执行结果
task1
task5
task4
task3
task2
ログイン後にコピー

5つのタスクの優先度は同じですが、キューの特性上、キューに参加した順にデータが返されるわけではないことがわかります。ヒープ:
1 、task1、task2、task3、task4、task5 がキューに登録されており、優先順位が同じであるため、ヒープは常に安定した状態になります。
2. デキューしてタスク 1 を取得すると、ヒープはまず構造をタスク 5、タスク 2、タスク 3、タスク 4 に調整し、安定した状態に達します。
3. デキューしてタスク 5 を取得すると、ヒープはまず構造をタスク 4、タスク 2、タスク 3 に調整し、安定した状態に達します。
4. デキューしてタスク 4 を取得すると、ヒープはまず構造をタスク 3、タスク 2 に調整し、安定した状態に達します。
5. デキューしてタスク 3 を取得します。ヒープはまず構造をタスク 2 に調整し、安定した状態に達します。
4. チームを離れ、タスク 2 を取得します。

Iterator, Countable

SplPriorityQueue は Iterator, Countable インターフェイスを実装しているため、foreach/count 関数で操作したり、rewind、valid、current、next/count メソッドを使用したりできます。

これはヒープ実装であるため、rewind メソッドは効果のない no-op 操作であることに注意してください。これは、ヘッド ポインターが常にヒープの先頭を指しているためです。つまり、current は常に次と等しいためです。単にさまようポインタである List とは異なり、top キューはヒープ要素を削除します (extract = current next (current はデキューされ、ヒープから削除されます))。

<?php
$splPriorityQueue = new \SplPriorityQueue();

$splPriorityQueue->insert("task1", 1);
$splPriorityQueue->insert("task2", 2);
$splPriorityQueue->insert("task3", 1);
$splPriorityQueue->insert("task4", 4);
$splPriorityQueue->insert("task5", 5);

echo "Countable: " . count($splPriorityQueue) . PHP_EOL;

// 迭代的话会删除队列元素 current 指针始终指向 top 所以 rewind 没什么意义
for ($splPriorityQueue->rewind(); $splPriorityQueue->valid();$splPriorityQueue->next()) { 
    var_dump($splPriorityQueue->current());
    var_dump($splPriorityQueue->count());
    $splPriorityQueue->rewind();
}

var_dump("is empty:" . $splPriorityQueue->isEmpty());
ログイン後にコピー

Extract dequeue

extract デキューはよりフレンドリーです。つまり、最も高い優先順位を持つ要素が常に返されます。優先順位が一貫している場合、データは次のようになります。ヒープ調整機能を使用して返されます。

<?php
$splPriorityQueue = new \SplPriorityQueue();

// data  priority
$splPriorityQueue->insert("task1", 1);
$splPriorityQueue->insert("task2", 2);
$splPriorityQueue->insert("task3", 1);
$splPriorityQueue->insert("task4", 4);
$splPriorityQueue->insert("task5", 5);

echo "Countable: " . count($splPriorityQueue) . PHP_EOL;

while (! $splPriorityQueue->isEmpty()) {
    var_dump($splPriorityQueue->extract());
    echo $splPriorityQueue->count() . PHP_EOL;
}
ログイン後にコピー

カスタム優先度処理メソッド

比較メソッドをオーバーライドして、独自の優先度処理メカニズムを定義します。

<?php
class CustomedSplPriorityQueue extends SplPriorityQueue
{
    public function compare($priority1, $priority2): int
    {
        // return $priority1 - $priority2;//高优先级优先
        return $priority2 - $priority1;//低优先级优先
    }
}

$splPriorityQueue = new \CustomedSplPriorityQueue();
$splPriorityQueue->setExtractFlags(SplPriorityQueue::EXTR_BOTH);
$splPriorityQueue->insert("task1", 1);
$splPriorityQueue->insert("task2", 2);
$splPriorityQueue->insert("task3", 1);
$splPriorityQueue->insert("task4", 4);
$splPriorityQueue->insert("task5", 5);
 
echo "Countable: " . count($splPriorityQueue) . PHP_EOL;

while (!$splPriorityQueue->isEmpty()) {
    var_dump($splPriorityQueue->extract());
}
ログイン後にコピー

この記事はここで終了しました。さらにエキサイティングなコンテンツについては、PHP 中国語 Web サイトの PHP ビデオ チュートリアル 列に注目してください。

以上がPHP プライオリティ キューの概要 (コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート