堆排序 Heapsort
堆排序:
由三个函数组成:
Max_heapify ( int A[] ,int i ,int heap_size)//堆化 T(n)=log(n);
Build_max_heap(int A[],int heap_size)//建堆 T(n)=n ;
Heap_sort(int A[],int length)//排序 T(n)=n*log(n);
1 #include<stdio.h> 2 //#include<stdlib.h> 3 4 void PrintArray(int data[] ,int length){ 5 int i; 6 for(i=0;i<length;i++){ 7 printf("%d ",data[i]); 8 } 9 printf("\n"); 10 } 11 12 //heap_size;堆的大小 13 // 堆化,保持堆的性质 14 // Max_Heapify让A[i]在最大堆中"下降", 15 // 使以i为根的子树成为最大堆 16 void Max_heapify( int A[] ,int i ,int heap_size){ 17 int l=2*i+1;//左子树下标 18 int r=2*i+2;//右子树下标 19 int largest,t; 20 if(l<heap_size&&A[l]>A[i]){ 21 largest=l; 22 } 23 else largest=i; 24 if(r<heap_size&&A[r]>A[largest]){ 25 largest=r; 26 } 27 if(largest!=i){ 28 t=A[i]; 29 A[i]=A[largest]; 30 A[largest]=t; 31 Max_heapify(A,largest,heap_size); 32 } 33 } 34 35 // 建堆 36 // 自底而上地调用MaxHeapify来将一个数组a[1..size]变成一个最大堆 37 Build_max_heap(int A[],int heap_size){ 38 int i; 39 for(i=heap_size/2;i>=0;i--){ 40 Max_heapify(A,i,heap_size); 41 } 42 } 43 44 // 堆排序 45 // 初始调用BuildMaxHeap将a[1..size]变成最大堆 46 // 因为数组最大元素在a[1],则可以通过将a[1]与a[size]互换达到正确位置 47 // 现在新的根元素破坏了最大堆的性质,所以调用MaxHeapify调整, 48 // 使a[1..size-1]成为最大堆,a[1]又是a[1..size-1]中的最大元素, 49 // 将a[1]与a[size-1]互换达到正确位置。 50 // 反复调用Heapify,使整个数组成从小到大排序。 51 // 注意: 交换只是破坏了以a[1]为根的二叉树最大堆性质,它的左右子二叉树还是具备最大堆性质。 52 // 这也是为何在BuildMaxHeap时需要遍历size/2到1的结点才能构成最大堆,而这里只需要堆化a[1]即可 53 Heap_sort(int A[],int length){ 54 int i,t; 55 int heap_size=length; 56 Build_max_heap(A,length); 57 printf("初始最大堆:\n"); 58 PrintArray(A,length); 59 for(i=length-1;i>=1;i--){ 60 t=A[i]; 61 A[i]=A[0]; 62 A[0]=t; 63 heap_size--; 64 Max_heapify(A,0,heap_size); 65 printf("中间过程:\n"); 66 PrintArray(A,length); 67 } 68 } 69 70 71 72 void main(){ 73 int A[]={4,6,1,8,15,2,17,9,3}; 74 int length=sizeof(A)/sizeof(A[0]); 75 Heap_sort(A,length); 76 printf("\n最后结果:\n"); 77 PrintArray(A,length); 78 }
结果:
时间复杂度为:n*logn