優先佇列學習總結

2021-09-13 09:45:28 字數 2635 閱讀 1539

普通的佇列,遵循先進先出的規則,進行元素的新增和查詢,但是對於很多情況下,我們想要在序列中找符合我們要求的元素(比如序列中最大的元素),這時候,無論是普通的線性表還是線性表中比較特殊的棧或者佇列,找到該指定元素的範圍都會卡在時間複雜度為o(n)的級別,其實我們完全可以實現查詢時間複雜度降為o(1),就是通過優先佇列來實現!

我們需要做的就是,給元素賦予一種優先順序(比如說:要是我們在使用中總想拿出佇列中最大的元素),我們建立佇列時,就將優先順序最高的元素放在隊首,最後想要的時候就可以直接拿走隊首元素了。也就是說整個優先佇列是按照優先順序從高到低建立出來的。

所以說,怎們實現這種設想呢?

實現以上想法,我們需要建立乙個最大堆(因為建最小堆是同樣的道理,所以之一最大堆為例來說明),如下圖:

易於操作,如果建立乙個陣列存這個完全二叉樹,以根節點開始下標為0,下面的子孫從左往右下標為1,2,3…可以發現:

左孩子節點下標 = 2×對應根節點下標+1 

右孩子節點下標 = 2×對應根節點下標+2

父親節點下標 = (孩子節點-1)/2

我們在往陣列中錄入資料時,將資料先新增到陣列最後乙個位置,然後根據以上公式將該葉子節點和其父親節點大小進行比較,如果比父親節點大的話,將父親節點移下來,用子節點提還,直到找到比當前新新增元素大的父親節點為止,以後新增節點都這樣整就行。這樣就使整個陣列將資料存為最大優先佇列的形式。

ps.這樣只保證了根為整個佇列的最大元素,並不能保證離根遠的葉子節點一定小於其他離根近葉子節點

要是出隊的話,將最大元素返回,然後要刪除佇列中的最大元素,這時就需要重新調整堆的結構了,怎樣調呢?

將陣列中最後乙個元素的調到根,並刪掉其對應的最後乙個位置,從根節點開始開始下沉,即就是

綜上,往堆中新增元素的時間複雜度為o(log(n)),從佇列中刪除元素的時間複雜度為o(log(n)),都比遍歷整個序列o(n)這個時間複雜度要小。

#include

#include

#include

using namespace std ;

#define max 65535

//最大堆實現

//保證子節點不大於其對應的父節點的值

//設定元素個數介面

//是否為空的介面

//獲取父親節點的介面

class dui

~dui()

public :

void

print()

add(i);}

cout <<

"這是乙個最大堆"

<< endl ;

for(

int i=

0; i <= last; i++

) cout <<

"當前最大堆頂部元素是"

<< endl ;

cout <<

getmax()

<< endl ;

cout <<

"堆尾元素"

<< endl ;

cout << p[last]

<

}//往堆中新增元素

void

add(

int e)

//交換父子節點資訊

void

swap

(int

& t1,

int& t2 )

//獲取堆的規模

intget_size()

//獲取其父親節點的下表

intgetparent

(int index)

//將新增的元素移動到正確的位置

void

siftup()

}//獲取其左孩子的下標

intget_right_child

(int index)

//獲取其右孩子的下標

intget_left_child

(int index)

//從堆頂開始比較父親節點和字節點的大小

//要是父親節點比其子節點要小的話,交換兩者的值

void

change

(int

& left,

int& right,

int& cur,

int& swaps)

//從堆頂調整使整個堆保持為完全二叉樹

void

siftdown()

}//如果左右節點都比其父親節點大,找最大的那個進行交換

else

if(p[cur]

< p[left]

&& p[cur]

< p[right]

)else

}else

else}}

}//從堆中取出最大元素

intgetmax()

//將最後乙個元素刪除掉

void

remove_last()

};///test 例子

intmain()

優先佇列學習總結

佇列 現實中我們最常見的是,去醫院 去銀行取錢,一般都需要排隊,這就是佇列,佇列有乙個最顯著的特徵 先進先出,一般情況下,大多都是先到先辦理,但是也是有特殊的情況,例如在醫院,萬一來個急診的,一定是急診的優先,或者在銀行,來個vip,有綠色通道。這種特殊的情況下,就是佇列中的特殊的佇列 優先佇列。它...

優先佇列學習

一 相關定義 優先佇列容器與佇列一樣,只能從隊尾插入元素,從隊首刪除元素。但是它有乙個特性,就是佇列中最大的元素總是位於隊首,所以出隊時,並非按照先進先出的原則進行,而是將當前佇列中最大的元素出隊。這點類似於給佇列裡的元素進行了由大到小的順序排序。元素的比較規則預設按元素值由大到小排序,可以過載 操...

佇列 優先佇列的學習

佇列定義 佇列是限定只能在表尾進行 插入,在表頭進行刪除的線性表 隊尾 允許插入的一端 隊頭 允許刪除的一端 佇列的定義 include queue 標頭檔案 using namespace std 需要加上使用名稱 空間,和sort 排序函式是一樣的。queue int q 格式 queue 型別...