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...