0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

什么是優(yōu)先隊(duì)列?漫畫形式帶你詳細(xì)了解優(yōu)先隊(duì)列

算法與數(shù)據(jù)結(jié)構(gòu) ? 來源:未知 ? 作者:易水寒 ? 2018-10-03 20:10 ? 次閱讀

這一次,我們來講一講二叉堆的另外一個應(yīng)用:優(yōu)先隊(duì)列

隊(duì)列的特點(diǎn)是什么?

聰明的小伙伴們都知道,是先進(jìn)先出(FIFO)。

入隊(duì)列:

出隊(duì)列:

那么,優(yōu)先隊(duì)列又是什么樣子呢?

優(yōu)先隊(duì)列不再遵循先入先出的原則,而是分為兩種情況:

最大優(yōu)先隊(duì)列,無論入隊(duì)順序,當(dāng)前最大的元素優(yōu)先出隊(duì)。

最小優(yōu)先隊(duì)列,無論入隊(duì)順序,當(dāng)前最小的元素優(yōu)先出隊(duì)。

比如有一個最大優(yōu)先隊(duì)列,它的最大元素是8,那么雖然元素8并不是隊(duì)首元素,但出隊(duì)的時候仍然讓元素8首先出隊(duì):

要滿足以上需求,利用線性數(shù)據(jù)結(jié)構(gòu)并非不能實(shí)現(xiàn),但是時間復(fù)雜度較高,最壞時間復(fù)雜度O(n),并不是最理想的方式。

至于為什么最壞時間復(fù)雜度是O(n),大家可以思考下。

讓我們回顧一下二叉堆的特性:

1.最大堆的堆頂是整個堆中的最大元素

2.最小堆的堆頂是整個堆中的最小元素

因此,我們可以用最大堆來實(shí)現(xiàn)最大優(yōu)先隊(duì)列,每一次入隊(duì)操作就是堆的插入操作,每一次出隊(duì)操作就是刪除堆頂節(jié)點(diǎn)。

入隊(duì)操作:

1.插入新節(jié)點(diǎn)5

2.新節(jié)點(diǎn)5上浮到合適位置。

出隊(duì)操作:

1.把原堆頂節(jié)點(diǎn)10“出隊(duì)”

2.最后一個節(jié)點(diǎn)1替換到堆頂位置

3.節(jié)點(diǎn)1下沉,節(jié)點(diǎn)9成為新堆頂

public class PriorityQueue {

privateint[] array;

privateint size;

publicPriorityQueue(){

//隊(duì)列初始長度32

array =newint[32];

}

/**

* 入隊(duì)

* @param key 入隊(duì)元素

*/

privatevoid enQueue(int key){

//隊(duì)列長度超出范圍,擴(kuò)容

if(size >= array.length){

resize();

}

array[size++]= key;

upAdjust();

}

/**

* 出隊(duì)

*/

privateint deQueue()throwsException{

if(size <=0){

thrownewException("the queue is empty !");

}

//獲取堆頂元素

int head = array[0];

//最后一個元素移動到堆頂

array[0]= array[--size];

downAdjust();

return head;

}

/**

* 上浮調(diào)整

*/

privatevoid upAdjust(){

int childIndex = size-1;

int parentIndex = childIndex/2;

// temp保存插入的葉子節(jié)點(diǎn)值,用于最后的賦值

int temp = array[childIndex];

while(childIndex >0&& temp > array[parentIndex])

{

//無需真正交換,單向賦值即可

array[childIndex]= array[parentIndex];

childIndex = parentIndex;

parentIndex = parentIndex /2;

}

array[childIndex]= temp;

}

/**

* 下沉調(diào)整

*/

privatevoid downAdjust(){

// temp保存父節(jié)點(diǎn)值,用于最后的賦值

int parentIndex =0;

int temp = array[parentIndex];

int childIndex =1;

while(childIndex < size){

// 如果有右孩子,且右孩子大于左孩子的值,則定位到右孩子

if(childIndex +1< size && array[childIndex +1]> array[childIndex]){

childIndex++;

}

// 如果父節(jié)點(diǎn)大于任何一個孩子的值,直接跳出

if(temp >= array[childIndex])

break;

//無需真正交換,單向賦值即可

array[parentIndex]= array[childIndex];

parentIndex = childIndex;

childIndex =2* childIndex +1;

}

array[parentIndex]= temp;

}

/**

* 下沉調(diào)整

*/

privatevoid resize(){

//隊(duì)列容量翻倍

int newSize =this.size *2;

this.array =Arrays.copyOf(this.array, newSize);

}

publicstaticvoid main(String[] args)throwsException{

PriorityQueue priorityQueue =newPriorityQueue();

priorityQueue.enQueue(3);

priorityQueue.enQueue(5);

priorityQueue.enQueue(10);

priorityQueue.enQueue(2);

priorityQueue.enQueue(7);

System.out.println("出隊(duì)元素:"+ priorityQueue.deQueue());

System.out.println("出隊(duì)元素:"+ priorityQueue.deQueue());

}

}

代碼中采用數(shù)組來存儲二叉堆的元素,因此當(dāng)元素超過數(shù)組范圍的時候,需要進(jìn)行resize來擴(kuò)大數(shù)組長度。

—————END—————

●編號755,輸入編號直達(dá)本文

●輸入m獲取文章目錄

推薦↓↓↓

人工智能與大數(shù)據(jù)技術(shù)

更多推薦《18個技術(shù)類公眾微信》

涵蓋:程序人生、算法與數(shù)據(jù)結(jié)構(gòu)、黑客技術(shù)與網(wǎng)絡(luò)安全、大數(shù)據(jù)技術(shù)、前端開發(fā)、Java、Python、Web開發(fā)、安卓開發(fā)、iOS開發(fā)、C/C++、.NET、Linux、數(shù)據(jù)庫、運(yùn)維等。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • fifo
    +關(guān)注

    關(guān)注

    3

    文章

    388

    瀏覽量

    43677
  • 數(shù)據(jù)結(jié)構(gòu)

    關(guān)注

    3

    文章

    573

    瀏覽量

    40130
  • 隊(duì)列
    +關(guān)注

    關(guān)注

    1

    文章

    46

    瀏覽量

    10893

原文標(biāo)題:漫畫:什么是優(yōu)先隊(duì)列?

文章出處:【微信號:TheAlgorithm,微信公眾號:算法與數(shù)據(jù)結(jié)構(gòu)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    FIFO隊(duì)列原理簡述

    FIFO是隊(duì)列機(jī)制中最簡單的,每個接口上只有一個FIFO隊(duì)列,表面上看FIFO隊(duì)列并沒有提供什么QoS保證,甚至很多人認(rèn)為FIFO嚴(yán)格意義上不算做一種隊(duì)列技術(shù),實(shí)則不然,F(xiàn)IFO是其它
    發(fā)表于 07-10 09:22 ?1665次閱讀

    請問使用郵箱、消息隊(duì)列、信號量進(jìn)行任務(wù)間通信時任務(wù)之間的切換要考慮優(yōu)先級嗎?

    使用郵箱、消息隊(duì)列、信號量進(jìn)行任務(wù)間通信時,任務(wù)之間的切換(在釋放信號量任務(wù)、請求信號量任務(wù)和其他任務(wù))之間仍需考慮優(yōu)先級嗎?
    發(fā)表于 04-22 06:14

    鴻蒙內(nèi)核源碼分析(調(diào)度隊(duì)列篇):進(jìn)程和Task的就緒隊(duì)列對調(diào)度的作用

    為何單獨(dú)講調(diào)度隊(duì)列?鴻蒙內(nèi)核代碼中有兩個源文件是關(guān)于隊(duì)列的,一個是用于調(diào)度的隊(duì)列,另一個是用于線程間通訊的IPC隊(duì)列。 本文詳細(xì)講述調(diào)度
    發(fā)表于 11-23 11:09

    干貨 | RTOS應(yīng)用中的優(yōu)先級反轉(zhuǎn)問題

    ,ControlTask任務(wù)得到的CPU減少。由于高優(yōu)先級的ServerTask任務(wù)占用了許多CPU時間,導(dǎo)致ControlTask無法及時讀取消息隊(duì)列中的數(shù)據(jù)。這是優(yōu)先反轉(zhuǎn)問題的一個例子,SamplerTask任務(wù)被
    發(fā)表于 03-09 15:00

    cubeMX+STM32+Freertos讀隊(duì)列時阻塞相關(guān)資料分享

    了超時時間。往隊(duì)列中寫數(shù)據(jù)的任務(wù)的優(yōu)先級低于讀隊(duì)列任務(wù)的優(yōu)先級。這意味著隊(duì)列中永遠(yuǎn)不會保持超過一個的數(shù)據(jù)單元。因?yàn)橐坏┯袛?shù)據(jù)被寫入
    發(fā)表于 02-14 06:07

    LabVIEW中的隊(duì)列使用詳解

    1現(xiàn)實(shí)中的隊(duì)列隊(duì)列估計(jì)是我們生活中出現(xiàn)的最頻繁的數(shù)據(jù)形式,各種類型的排隊(duì)例如銀行叫號辦理業(yè)務(wù),購買火車票飛機(jī)票、排隊(duì)打飯、汽車燈等待紅綠燈然后放行、流水線上下架的產(chǎn)品或零部件等都屬于隊(duì)列,與之相反
    發(fā)表于 09-05 00:07

    優(yōu)先隊(duì)列的千兆以太網(wǎng)MAC設(shè)計(jì)

    在以太網(wǎng)應(yīng)用越來越廣泛的背景下,針對某局域網(wǎng)具有傳輸數(shù)據(jù)量大和保持部分?jǐn)?shù)據(jù)實(shí)時性的特點(diǎn),采用了包含兩種不同優(yōu)先級幀的千兆以太網(wǎng)方案。基于Actel FPGA設(shè)計(jì)了一種帶優(yōu)先級隊(duì)
    發(fā)表于 05-03 18:17 ?43次下載
    帶<b class='flag-5'>優(yōu)先</b>級<b class='flag-5'>隊(duì)列</b>的千兆以太網(wǎng)MAC設(shè)計(jì)

    堆和堆的應(yīng)用:堆排序和優(yōu)先隊(duì)列

    堆(Heap))是一種重要的數(shù)據(jù)結(jié)構(gòu),是實(shí)現(xiàn)優(yōu)先隊(duì)列(Priority Queues)首選的數(shù)據(jù)結(jié)構(gòu)。
    的頭像 發(fā)表于 03-16 11:32 ?3771次閱讀
    堆和堆的應(yīng)用:堆排序和<b class='flag-5'>優(yōu)先</b><b class='flag-5'>隊(duì)列</b>

    Linux IPC POSIX 消息隊(duì)列

    POSIX mq VS Sys V mq的優(yōu)勢更簡單的基于文件的應(yīng)用接口完全支持消息優(yōu)先級(優(yōu)先級最終決動隊(duì)列中消息的位置)完全支持消息到達(dá)的異步通知,這通過信號或是線程創(chuàng)建實(shí)現(xiàn)用于阻塞
    發(fā)表于 04-02 14:46 ?581次閱讀

    cubeMX+STM32+Freertos 讀隊(duì)列時阻塞

    了超時時間。往隊(duì)列中寫數(shù)據(jù)的任務(wù)的優(yōu)先級低于讀隊(duì)列任務(wù)的優(yōu)先級。這意味著隊(duì)列中永遠(yuǎn)不會保持超過一個的數(shù)據(jù)單元。因?yàn)橐坏┯袛?shù)據(jù)被寫入
    發(fā)表于 12-09 15:21 ?10次下載
    cubeMX+STM32+Freertos 讀<b class='flag-5'>隊(duì)列</b>時阻塞

    詳細(xì)了解隊(duì)列的特點(diǎn)及用處

    先進(jìn)先出,隊(duì)列是一種操作受限的線性表,其限制條件為允許在表的一端進(jìn)行插入,而在表的另一端進(jìn)行刪除。插入的一端叫做隊(duì)尾,刪除的一端叫做隊(duì)頭。向隊(duì)列中插入新元素的行為稱為進(jìn)隊(duì),從隊(duì)列中刪除元素的行為稱為出隊(duì)。一般用法在隊(duì)頭插入,在隊(duì)
    的頭像 發(fā)表于 05-31 15:25 ?7895次閱讀
    <b class='flag-5'>詳細(xì)了解</b><b class='flag-5'>隊(duì)列</b>的特點(diǎn)及用處

    隊(duì)列Queue的常用方法有哪些

    FIFO(先入先出)隊(duì)列Queue,LIFO(后入先出)隊(duì)列LifoQueue,和優(yōu)先隊(duì)列PriorityQueue。
    的頭像 發(fā)表于 08-19 10:24 ?5752次閱讀
    <b class='flag-5'>隊(duì)列</b>Queue的常用方法有哪些

    什么是消息隊(duì)列?消息隊(duì)列中間件重要嗎?

    應(yīng)用解耦:消息隊(duì)列減少了服務(wù)之間的耦合性,不同的服務(wù)可以通過消息隊(duì)列進(jìn)行通信,而不用關(guān)心彼此的實(shí)現(xiàn)細(xì)節(jié)。
    的頭像 發(fā)表于 11-07 14:55 ?1421次閱讀

    RTOS消息隊(duì)列的應(yīng)用

    基于RTOS的應(yīng)用中,通常使用隊(duì)列機(jī)制實(shí)現(xiàn)任務(wù)間的數(shù)據(jù)交互,一個應(yīng)用程序可以有任意數(shù)量的消息隊(duì)列,每個消息隊(duì)列都有自己的用途。
    發(fā)表于 05-29 10:49 ?631次閱讀
    RTOS消息<b class='flag-5'>隊(duì)列</b>的應(yīng)用

    FreeRTOS消息隊(duì)列介紹

    隊(duì)列是為了任務(wù)與任務(wù)、任務(wù)與中斷之間的通信而準(zhǔn)備的,可以在任務(wù)與任務(wù)、任務(wù)與中斷之間傳遞消息,隊(duì)列中可以存儲有限的、大小固定的數(shù)據(jù)項(xiàng)目。任務(wù)與任務(wù)、任務(wù)與中斷之間要交流的數(shù)據(jù)保存在隊(duì)列中,叫做
    的頭像 發(fā)表于 07-06 16:58 ?809次閱讀
    FreeRTOS消息<b class='flag-5'>隊(duì)列</b>介紹