摘要:迭代的話會(huì)刪除隊(duì)列元素指針始終指向所以沒什么意義出隊(duì)出隊(duì)更為友好,即始終返回優(yōu)先級最高的元素,優(yōu)先級相投時(shí)會(huì)以堆調(diào)整的特性返回?cái)?shù)據(jù)。自定義優(yōu)先級處理方式重寫方法定義自己的優(yōu)先級處理機(jī)制。高優(yōu)先級優(yōu)先低優(yōu)先級優(yōu)先
PHP 的 SPL 庫內(nèi)置了 SplPriorityQueue優(yōu)先級隊(duì)列,并且是以Heap數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,默認(rèn)為MaxHeap模式,即priority越大越優(yōu)先出隊(duì),同時(shí)可以通過重寫compare方法來使用MinHeap(優(yōu)先級越低越優(yōu)先出隊(duì),場景貌似很少吧)。
SplPriorityQueue 堆特性這里需要注意并理解:SplPriorityQueue是以堆數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)的,當(dāng)我們出隊(duì)時(shí)會(huì)拿出堆頂的元素,此時(shí)堆的特性被破壞,堆會(huì)進(jìn)行相應(yīng)的調(diào)整至穩(wěn)定態(tài)(MaxHeap or MinHeap),即會(huì)將最后一個(gè)元素替換到堆頂,然后進(jìn)行穩(wěn)定態(tài)驗(yàn)證,不符合堆特性則繼續(xù)調(diào)整,或者我們就得到了一個(gè)穩(wěn)定態(tài)的堆,所以當(dāng)優(yōu)先級相同,出隊(duì)順序并不會(huì)按照入隊(duì)順序。
源碼示例:
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; //執(zhí)行結(jié)果 task1 task5 task4 task3 task2
可以看到,雖然 5 個(gè)任務(wù)的優(yōu)先級相同,但隊(duì)列并沒有按照入隊(duì)順序返回?cái)?shù)據(jù),因?yàn)?b>堆的特性使然:
1、入隊(duì) task1, task2, task3, task4, task5,因?yàn)閮?yōu)先級相同,所以堆一直處于穩(wěn)定態(tài)。
2、出隊(duì),得 task1,堆先將結(jié)構(gòu)調(diào)整為 task5, task2, task3, task4,已然達(dá)到了穩(wěn)定態(tài)。
3、出隊(duì),得 task5,堆先將結(jié)構(gòu)調(diào)整為 task4, task2, task3,已然達(dá)到了穩(wěn)定態(tài)。
4、出隊(duì),得 task4,堆先將結(jié)構(gòu)調(diào)整為 task3, task2,已然達(dá)到了穩(wěn)定態(tài)。
5、出隊(duì),得 task3,堆先將結(jié)構(gòu)調(diào)整為 task2,已然達(dá)到了穩(wěn)定態(tài)。
4、出隊(duì),得 task2。
SplPriorityQueue實(shí)現(xiàn)了 Iterator, Countable接口,所以我們可以foreach/count函數(shù)操作它,或者使用rewind,valid,current,next/count方法。
注意,因?yàn)槭?b>堆實(shí)現(xiàn),所以rewind方法是一個(gè)no-op沒有什作用的操作,因?yàn)?b>頭指針始終指向堆頂,即current始終等于top,不像List只是游走指針,出隊(duì)是會(huì)刪除堆元素的,extract = current + next(current出隊(duì),從堆中刪除)。
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; // 迭代的話會(huì)刪除隊(duì)列元素 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出隊(duì)
extract 出隊(duì)更為友好,即始終返回優(yōu)先級最高的元素,優(yōu)先級相投時(shí)會(huì)以堆調(diào)整的特性返回?cái)?shù)據(jù)。
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; }自定義優(yōu)先級處理方式
重寫compare方法定義自己的優(yōu)先級處理機(jī)制。
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()); }
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/31100.html
摘要:普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭取出。在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級。當(dāng)訪問元素時(shí),具有最高優(yōu)先級的元素最先取出。優(yōu)先隊(duì)列具有最高級先出,的行為特征。 普通的隊(duì)列是一種先進(jìn)先出的數(shù)據(jù)結(jié)構(gòu),元素在隊(duì)列尾追加,而從隊(duì)列頭取出。在優(yōu)先隊(duì)列中,元素被賦予優(yōu)先級。當(dāng)訪問元素時(shí),具有最高優(yōu)先級的元素最先取出。優(yōu)先隊(duì)列具有最高級先出 (largest-in,first...
摘要:官網(wǎng)源碼解讀號(hào)外號(hào)外歡迎大家我們開發(fā)組定了一個(gè)就線下聚一次的小目標(biāo)里面的框架算是非常重的了這里的重先不具體到性能層面主要是框架的設(shè)計(jì)思想和框架集成的服務(wù)讓框架可以既可以快速解決很多問題又可以輕松擴(kuò)展中的框架有在應(yīng)該無出其右了這次解讀的源碼 官網(wǎng): https://www.swoft.org/源碼解讀: http://naotu.baidu.com/file/8... 號(hào)外號(hào)外, 歡迎大...
摘要:場景說明用于處理比較耗時(shí)的請求,例如批量發(fā)送郵件,如果直接在網(wǎng)頁觸發(fā)執(zhí)行發(fā)送,程序會(huì)出現(xiàn)超時(shí)高并發(fā)場景,當(dāng)某個(gè)時(shí)刻請求瞬間增加時(shí),可以把請求寫入到隊(duì)列,后臺(tái)在去處理這些請求搶購場景,先入先出的模式命令或往列表右側(cè)推入數(shù)據(jù)客戶端阻塞直到隊(duì)列有 場景說明: 用于處理比較耗時(shí)的請求,例如批量發(fā)送郵件,如果直接在網(wǎng)頁觸發(fā)執(zhí)行發(fā)送,程序會(huì)出現(xiàn)超時(shí) 高并發(fā)場景,當(dāng)某個(gè)時(shí)刻請求瞬間增加時(shí),可以把請...
摘要:場景說明用于處理比較耗時(shí)的請求,例如批量發(fā)送郵件,如果直接在網(wǎng)頁觸發(fā)執(zhí)行發(fā)送,程序會(huì)出現(xiàn)超時(shí)高并發(fā)場景,當(dāng)某個(gè)時(shí)刻請求瞬間增加時(shí),可以把請求寫入到隊(duì)列,后臺(tái)在去處理這些請求搶購場景,先入先出的模式命令或往列表右側(cè)推入數(shù)據(jù)客戶端阻塞直到隊(duì)列有 場景說明: 用于處理比較耗時(shí)的請求,例如批量發(fā)送郵件,如果直接在網(wǎng)頁觸發(fā)執(zhí)行發(fā)送,程序會(huì)出現(xiàn)超時(shí) 高并發(fā)場景,當(dāng)某個(gè)時(shí)刻請求瞬間增加時(shí),可以把請...
閱讀 2554·2021-11-23 09:51
閱讀 598·2019-08-30 13:59
閱讀 1901·2019-08-29 11:20
閱讀 2583·2019-08-26 13:41
閱讀 3305·2019-08-26 12:16
閱讀 790·2019-08-26 10:59
閱讀 3399·2019-08-26 10:14
閱讀 657·2019-08-23 17:21