建堆既可以用堆調整方法將原數組調整為一個堆,也可以藉助往堆中插入元素的方法從無到有的建立一個堆。
兩種方法比較:
(1)藉助堆調整建堆的時間複雜度為O(n)。藉助插入法建堆的時間複雜度為O(nlgn) ,書上第二問要求證明這個複雜度,但是我認為插入法的複雜度也是O(n),因為它和堆調整的區別在於針對每個節點i,堆調整是自上向下進行調整,插入法是自下向上進行調整。
(2)對於同樣的輸入兩個方法建立的堆可能不同。因為堆調整時,是i要跟它的兩個子女進行比較,選出最大(小)的,但是插入x時,x只跟它的父節點進行比較。比如輸入為2、3、4,堆調整建堆為4、3、2,插入法建堆為4、2、3。
插入法建最大堆代碼如下:
#include <stdio.h>#include <string.h>#include <time.h>#define BUFFER_SIZE 10//將最大堆指定元素x的關鍵字增大到k,k要大於x原關鍵字 void HeapIncreaseKey(int *a,int x,int k){int tmp=0;if(k<=a[x]){return;}a[x]=k;while(x>1&&a[x]>a[x>>1]){tmp=a[x];a[x]=a[x>>1];a[x>>1]=tmp;x=x>>1;}}//插入元素到最大堆 void MaxHeapInsert(int *a,int k,int *heapSize){int tmp=k-1;(*heapSize)++;a[*heapSize]=tmp;HeapIncreaseKey(a,*heapSize,k);}//插入法建堆void BuildMaxHeap(int *b,int len,int *a,int *heapSize){int i=0;for(i=0;i<len;i++){MaxHeapInsert(a,b[i],heapSize);}} int main(){int i=0;int j=0;int heapSize=0;int a[BUFFER_SIZE+1];int b[BUFFER_SIZE];//隨機產生鏈表,k=4 srand((unsigned)time(NULL));for(i=0;i<BUFFER_SIZE;i++){b[i]=rand()%BUFFER_SIZE;} printf("隨機產生的鏈表:\n");for(i=0;i<BUFFER_SIZE;i++){printf("%d ",b[i]);}printf("\n插入法建堆:\n"); BuildMaxHeap(b,BUFFER_SIZE,a,&heapSize);for(i=1;i<=BUFFER_SIZE;i++){printf("%d ",a[i]);}system("pause");return 0;}