優先順序佇列

2021-08-19 11:58:00 字數 3953 閱讀 4992

5 左高樹

6 堆排序

與fifo結構的佇列不同,在優先順序佇列當中,元素出佇列的順序是由元素的優先順序決定。可以按照優先順序的遞增順序,也可以按優先順序的遞減順序,但不是元素進入佇列的順序。

堆是實現優先順序佇列的效率很高的資料結構。c++的stl類priority-queue是用堆實現的優先順序佇列。下面主要介紹堆和左高樹。

優先順序佇列(priority queue)是0個或多個元素的集合,每個元素都有乙個優先權或值,對優先順序佇列進行的操作有:

1)查詢乙個元素;

2)插入乙個新元素;

3)刪除乙個元素。

與這些操作分別對應的函式是top、push和pop。在最小優先順序佇列中(min priority queue)中,查詢和刪除的元素都是優先順序最小的元素;在最大優先順序佇列(max priority queue)當中,查詢和刪除的元素都是優先順序最大的元素。優先順序佇列的元素可以有相同的優先順序,對這樣的元素,查詢和刪除可以按照任意順序處理。

舉例:假設我們對一台機器所提供的服務按固定時間收費(如,按天或按月)。每個使用者的付費是相同的。假設機器在任何時候都可以服務,為了獲得最大的收益,我們把等待機器服務的使用者組成乙個最小的優先順序佇列。優先順序是使用者所需的服務時間。當乙個使用者需要機器服務時,他的請求就被加到優先順序佇列。一旦機器空閒,服務時間需求最小(即優先順序最大時)的使用者便最先得到服務。

最大優先順序佇列的抽象資料型別說明如下:

抽象資料型別 maxpriorityqueue

下面的程式是c++抽象資料類

template

class maxpriorityqueue

virtual

bool empty() const=0;

virtual

int size() const=0;

virtual

const t& top()=0;

virtual

void pop()=0;

virtual

void push(const t& theelement)=0;

};

1.一棵大根樹(小根樹)是這樣一棵樹,其中每個節點的值都大於(小於)或等於其子節點(如果有子節點的話)的值。

2.乙個大根堆(小根堆)既是大根樹(小根樹)也是完全二叉樹。

插入策略:從乙個葉子到根進行一次起泡過程。每一次的操作需要耗時o(1)。因此,實現這種插入策略的時間複雜性為o(height)=o(log n)。

程式如下(複雜度為o(log n))

template

void maxheap::push(const t& theelement)

int currentnode=++heapsize;

while(currentnode!=1 && heap[currentnode/2]2];

currentnode/=2;

} heap[currentnode]=theelement;

}

刪除策略

1、刪除要刪除的節點的值;

2、確定刪除後的結構為完全二叉樹,並儲存多餘的節點的值a;

3、確定a的位置:沿著刪除節點到a原先的位置的路徑,不斷調整節點的值,確保其為大根堆。

程式如下(刪除最大元素,複雜度為o(log n))

template

void maxheap::pop()

heap[currentnode]=lastelement;//放進去吧

}

初始化策略:從最後個具有孩子節點的地方進行檢查,如果以這個元素的為根的子樹是大根堆,則不做操作。如果不是大根堆則進行調整為大根堆,然後依次檢查上乙個節點為根的子樹是否是大根堆,直至檢查到根節點為止

程式如下(複雜度為o(n)):

template

void maxheap::initialize(t *theheap,int thesize)

heap[child/2]=rootelement;//放進去吧

}}

1、一棵二叉樹稱為高度優先左高樹(hblt),當且僅當其任何乙個內部節點的左孩子的s值都大於或等於右孩子的s值。令s(x)是從節點x到其子樹的外部節點的所有路徑中最短的一條,若x是外部節點,則s的值為0;若x為內部節點,則s的值為:min+1

2、若一棵hblt同時還是大根樹,則稱最大hblt。若一棵hblt同時還是小根樹,則稱最小hblt

當兩個優先順序佇列或多個長度不同的佇列需要合併的時候,就用到左高樹了

插入策略:最大hblt的插入操作可以利用最大hblt的合併操作來實現。假定將元素x插入到名為h的最大hblt當中,則先建立一棵新的只含這個元素的hblt,然後和原來的hblt合併

template

void maxhblt::push(const t& theelement)

刪除策略:最大元素在根中,因此根被刪除可以看做是兩個左右子樹的合併。

template

void maxhblt::pop()

合併策略:用遞迴實現。

1、首先比較兩個樹的根的大小,將大的根作為合併後的根;

2、將大的根的樹右子樹與小的根的樹進行合併,合併後的樹作為其新的右子樹;

3、判斷是否滿足最大hblt的定義,若不符合則進行左右翻轉。

合併兩棵左高樹程式:

template

void maxhblt

::meld(binarytreenode<

pair

>*

&x, binarytreenode<

pair

>*

&y) if(x->element.secondelement.second)//確保x為較大的根並成為新根

swap(x,y);

meld(x->rightchild,y);//x的右孩子和y合併

if(x->leftchild==

null)

else }

template

void maxhblt

::meld(maxhblt& thehblt)

初始化策略:將n個元素逐個插入最空的最大hblt當中,首先建立n個僅含有乙個元素的最大hblt,這n個樹組成乙個fifo的佇列,然後成對刪除hblt,將其合併再插入到佇列末尾,直到佇列只有一棵hblt為止。

templatevoid maxhblt::initialize(t* theelements,int thesize)

if(thesize>0)

root=q.front();

treesize=thesize;

}

deactivatearray將maxheap::heap置為null。這一步是必要的,因為maxheap::initialize置maxheap::heap為陣列a,當堆排序函式退出時,大根堆析構函式將刪除maxheap::heap。因此,為防止陣列a被刪除,需要呼叫deactivatearray

template

void heapsort(t a,int n)

heap.deactivatearray();//從堆的析構函式中儲存陣列a

}

佇列 優先順序佇列

優先順序佇列的隊尾是不需要改變的,永遠在低下標處。當佇列增加資料時,隊頭的位置就是資料項的大小減去1.public class priorityq 插入 public void insert long item else quearray j 1 item nitem 刪除 public long ...

優先順序佇列

分為最小優先順序佇列和最大優先順序佇列。優先順序佇列是一種用來維護一組元素構成的集合s的資料結構,這一組元素都有乙個關鍵字key,乙個最大優先順序佇列支援的操作 insert s,x 把x插入到集合s中 maxmum s 返回s中最大元素 extra max s 去掉s中最大關鍵字並返回該最大關鍵子...

優先順序佇列

1 include stdafx.h 2 include3 4 using namespace std 5 6 define max heap len 107 int heap max heap len 8 int heap size 0 the number of elements in heap...