普通的佇列,遵循先進先出的規則,進行元素的新增和查詢,但是對於很多情況下,我們想要在序列中找符合我們要求的元素(比如序列中最大的元素
),這時候,無論是普通的線性表還是線性表中比較特殊的棧或者佇列,找到該指定元素的範圍都會卡在時間複雜度為o(n)的級別,其實我們完全可以實現查詢時間複雜度降為o(1),就是通過優先佇列來實現!
我們需要做的就是,給元素賦予一種優先順序
(比如說:要是我們在使用中總想拿出佇列中最大的元素),我們建立佇列時,就將優先順序最高的元素放在隊首,最後想要的時候就可以直接拿走隊首元素了。也就是說整個優先佇列是按照優先順序從高到低建立出來的。
所以說,怎們實現這種設想呢?
實現以上想法,我們需要建立乙個最大堆(因為建最小堆是同樣的道理,所以之一最大堆為例來說明
),如下圖:
易於操作,如果建立乙個陣列存這個完全二叉樹,以根節點開始下標為0,下面的子孫從左往右下標為1,2,3…可以發現:
左孩子節點下標 = 2×對應根節點下標+1
右孩子節點下標 = 2×對應根節點下標+2
父親節點下標 = (孩子節點-1)/2
我們在往陣列中錄入資料時,將資料先新增到陣列最後乙個位置,然後根據以上公式將該葉子節點和其父親節點大小進行比較,如果比父親節點大的話,將父親節點移下來,用子節點提還,直到找到比當前新新增元素大的父親節點為止,以後新增節點都這樣整就行。這樣就使整個陣列將資料存為最大優先佇列的形式。
ps.這樣只保證了根為整個佇列的最大元素,並不能保證離根遠的葉子節點一定小於其他離根近葉子節點
要是出隊的話,將最大元素返回,然後要刪除佇列中的最大元素,這時就需要重新調整堆的結構了,怎樣調呢?
將陣列中最後乙個元素的調到根,並刪掉其對應的最後乙個位置,從根節點開始開始下沉
,即就是
#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 型別...