算法導論 第六章:優先級隊列

        雖然堆排序的時間複雜度爲O(nlgn),但在實際中,快速排序(下一章將介紹)往往要優於堆排序。儘管如此,堆數據結構在其他方面有着很大的用處,如用於優先級隊列的實現。因爲堆可讓優先級隊列的所有操作的時間複雜度爲O(lgn)。最大優先級隊列常用於共享主機上的作業調度,最小優先級隊列常用於事件驅動的模擬中。

以最大優先級隊列爲例,其支持的操作如下:

1)INSERT(S,x): 向集合中插入元素x


2)MAXIMUM(S): 返回集合S的最大值


3)EXTRACT-MAX(S):刪除集合S的最大值


4)INCREASE-KEY(S,x,k):將集合S中的元素x的值增加爲k


最大優先級隊列實現的完整代碼如下:

#include<iostream>
#include<cstdlib>
#include<climits>
#define PARENT(i) (i/2)
#define LEFT(i)   (2*i)
#define RIGHT(i)  (2*i+1)
using namespace std;

void Print(int *a)
{
	int n=a[0];
	for(int i=1;i<=n;i++)
		cout<<a[i]<<"   ";
	cout<<endl;
	}
int *Transform(int *a,int n)
{
  int * A=new int[n+1];
   A[0]=n;
   for(int i=0;i<n;i++)
	   A[i+1]=a[i];
   return A;	
	}
void swap(int &a,int &b)
{
	int temp;
	temp=a;
	a=b;
	b=temp;
	}
void Max_Heapify(int *A,int i)
{//adjust the heap to maintain the heap property
	int heap_size=A[0];
	int l=LEFT(i) ;   //index of i's left child
	int r=RIGHT(i);
	int largest;     //At each step,the largest of the element A[i],A[LEFT(i)]
					 //A[RIGHT(i)] is determined,and its index is stored in largest. 
	if(l<=heap_size && A[l]>A[i])
		largest	= l;
	else
		largest = i;

	if(r<=heap_size && A[r]>A[largest])
		largest = r;
	
	if(largest!=i)     //the subtree rooted at i violate the max-heap property
	{ 
		swap(A[i],A[largest]);
		Max_Heapify(A,largest);  //after exchanging ,the subtree rooted at largest might violate the max-heap property
 		}
	}
void Build_MaxHeap(int *A)
{//Transform array A into max-heap A,where A[0]=heap-size
	int A_length=A[0];
	for(int i=A_length/2;i>=1;i--)
		Max_Heapify(A,i);	
	}
int GetHeapMaximum(int *A)
{//return the elements of S with the largest key
	Build_MaxHeap(A);
	return A[1];
	}
int Heap_ExtractMax(int *A)
{
	int max;
	int heap_size;
	heap_size=A[0];
	if(heap_size<1)
	{ 
		cout<<"heap underflow"<<endl;
		return -1;
		}
	Build_MaxHeap(A);
	max=A[1];
	A[1]=A[heap_size];
	heap_size--;
	A[0]=heap_size;
	Max_Heapify(A,1);
	
	return max;
	}
void Heap_IncreaseKey(int *A,int i,int key)
{
	Build_MaxHeap(A);
	   if(key<A[i]){
		cout<<"new key is smaller than the current key."<<endl;
		return;
		}
	A[i]=key;
	while(i>1 && A[PARENT(i)]<A[i])
	 {
		swap(A[PARENT(i)],A[i]);
		i=PARENT(i);	
	 	}
	}
void Heap_InsertKey(int *A,int key)
{
	int heap_size=A[0];
	heap_size=heap_size+1;
	A[0]=heap_size;
	A[heap_size]=INT_MIN;
	Heap_IncreaseKey(A,heap_size,key);
	}
int main(){
	
	int a[]={4,1,3,2,16,9,10,14,8,7};
	int n=sizeof(a)/sizeof(int);
	int *A=new int[n+1];

	cout<<"---------------Init the set--------------------"<<endl;
	cout<<"After initing,S[1..n] is:"<<endl;
	A=Transform(a,n);   //Transform a[0...n-1] into a[1...n];a[0]=a.length
	Print(A);
	
	cout<<"---------------Excute MAXIMUM------------------"<<endl;
	int hMaxN;
	hMaxN=GetHeapMaximum(A);
	cout<<"The largest key is:"<<hMaxN<<endl;
	
	cout<<"------------Excute EXTRACT-MAX-----------------"<<endl;
	hMaxN=Heap_ExtractMax(A);
	cout<<"The largest key is:"<<hMaxN<<endl;
	cout<<"After removing the largest,the heap is:"<<endl;
	Print(A);
	
	cout<<"------------Excute INCREASE-KEY----------------"<<endl;
	int key=11;
	int index=6;
	Heap_IncreaseKey(A,index,key);
	cout<<"After increasing ,the heap is:"<<endl;
	Print(A);
	
	cout<<"--------------Excute HEAP-INSERT---------------"<<endl;
	int ikey=13;
	Heap_InsertKey(A,ikey);
	Print(A);
	cout<<"-----------------------------------------------"<<endl;
	return 0;
	}



運行結果如下:



若有錯誤,請指正~~~


發佈了42 篇原創文章 · 獲贊 13 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章