日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

漫画:什么是优先队列

發(fā)布時(shí)間:2023/12/3 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 漫画:什么是优先队列 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)載自??漫畫:什么是優(yōu)先隊(duì)列

在之前的漫畫中,我們介紹了二叉堆和堆排序。沒看過的小伙伴可以看一看前文:

漫畫:什么是二叉堆?(修正版)

漫畫:什么是堆排序?

這一次,我們來講一講二叉堆的另外一個(gè)應(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ì)。

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

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

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

?

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

1.最大堆的堆頂是整個(gè)堆中的最大元素

2.最小堆的堆頂是整個(gè)堆中的最小元素

因此,我們可以用最大堆來實(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.最后一個(gè)節(jié)點(diǎn)1替換到堆頂位置

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

?

public class PriorityQueue { private int[] array; private int size;public PriorityQueue(){//隊(duì)列初始長(zhǎng)度32array = new int[32]; }/** * 入隊(duì) * @param key ?入隊(duì)元素 */ private void enQueue(int key) {//隊(duì)列長(zhǎng)度超出范圍,擴(kuò)容if(size >= array.length){resize();}array[size++] = key;upAdjust(); }/** * 出隊(duì) */ private int deQueue() throws Exception {if(size <= 0){throw new Exception("the queue is empty !");}//獲取堆頂元素int head = array[0];//最后一個(gè)元素移動(dòng)到堆頂array[0] = array[--size];downAdjust();return head; }/** * 上浮調(diào)整 */ private void 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)整 */ private void 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)大于任何一個(gè)孩子的值,直接跳出if (temp >= array[childIndex])break;//無需真正交換,單向賦值即可array[parentIndex] = array[childIndex];parentIndex = childIndex;childIndex = 2 * childIndex + 1;}array[parentIndex] = temp; }/** * 擴(kuò)容調(diào)整 */ private void resize() {//隊(duì)列容量翻倍int newSize = this.size * 2;this.array = Arrays.copyOf(this.array, newSize); }public static void main(String[] args) throws Exception {PriorityQueue priorityQueue = new PriorityQueue();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ù)組來存儲(chǔ)二叉堆的元素,因此當(dāng)元素超過數(shù)組范圍的時(shí)候,需要進(jìn)行resize來擴(kuò)大數(shù)組長(zhǎng)度。

?

總結(jié)

以上是生活随笔為你收集整理的漫画:什么是优先队列的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。