RM新时代网站-首页

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

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

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

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

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

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

隊列的特點是什么?

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

入隊列:

出隊列:

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

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

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

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

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

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

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

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

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

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

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

入隊操作:

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

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

出隊操作:

1.把原堆頂節(jié)點10“出隊”

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

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

public class PriorityQueue {

privateint[] array;

privateint size;

publicPriorityQueue(){

//隊列初始長度32

array =newint[32];

}

/**

* 入隊

* @param key 入隊元素

*/

privatevoid enQueue(int key){

//隊列長度超出范圍,擴容

if(size >= array.length){

resize();

}

array[size++]= key;

upAdjust();

}

/**

* 出隊

*/

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é)點值,用于最后的賦值

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é)點值,用于最后的賦值

int parentIndex =0;

int temp = array[parentIndex];

int childIndex =1;

while(childIndex < size){

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

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

childIndex++;

}

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

if(temp >= array[childIndex])

break;

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

array[parentIndex]= array[childIndex];

parentIndex = childIndex;

childIndex =2* childIndex +1;

}

array[parentIndex]= temp;

}

/**

* 下沉調(diào)整

*/

privatevoid resize(){

//隊列容量翻倍

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("出隊元素:"+ priorityQueue.deQueue());

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

}

}

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

—————END—————

●編號755,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

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

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

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

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

    關(guān)注

    3

    文章

    387

    瀏覽量

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

    關(guān)注

    3

    文章

    573

    瀏覽量

    40121
  • 隊列
    +關(guān)注

    關(guān)注

    1

    文章

    46

    瀏覽量

    10893

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

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

收藏 人收藏

    評論

    相關(guān)推薦

    FIFO隊列原理簡述

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

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

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

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

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

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

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

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

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

    LabVIEW中的隊列使用詳解

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

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

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

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

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

    Linux IPC POSIX 消息隊列

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

    cubeMX+STM32+Freertos 讀隊列時阻塞

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

    詳細了解隊列的特點及用處

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

    隊列Queue的常用方法有哪些

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

    什么是消息隊列?消息隊列中間件重要嗎?

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

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

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

    FreeRTOS消息隊列介紹

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