堆排序过程:
1:建立堆(大根堆或者小根堆)
2:交换第一个和最后一个。
3:堆调整。
其实整个过程最核心的算法就是对调整:
1 #include <stdio.h> 2 3 //交换 4 static void swap(void *a[], int i, int j){ 5 void *tmp; 6 tmp = a[i]; 7 a[i] = a[j]; 8 a[j] = tmp; 9 } 10 11 //堆调整 12 static void heapify(void **ar, int(*cmp)(const void *, const void *), int idx, int max){ 13 int left = 2 * idx + 1; 14 int right = 2 * idx + 2; 15 int largest = idx; 16 if(idx < max/2){//如果idx是叶节点就不用进行调整 17 if(left < max && cmp(ar[left], ar[largest]) > 0){ 18 largest = left; 19 } 20 if(right < max && cmp(ar[right], ar[largest]) > 0){ 21 largest = right; 22 } 23 if(largest != idx){ //如果最大节点不是父节点,那么递归进行交换 24 swap(ar, idx, largest); 25 heapify(ar, cmp, largest, max); //避免调整之后以max为父节点的子树不是堆 26 } 27 } 28 } 29 30 //建立堆 31 static void buildHeap(void **ar, int(*cmp)(const void *, const void *), int n){ 32 int i; 33 for(i = n/2 - 1; i >= 0; i--){ 34 heapify(ar, cmp, i, n); 35 } 36 } 37 38 void heapSort(void **ar, int n, int (*cmp)(const void *, const void *)){ 39 int i; 40 buildHeap(ar, cmp, n); 41 for(i = n - 1; i >= 1; i--){ 42 swap(ar, 0, i);//交换第一个和最后一个 43 heapify(ar, cmp, 0, i); 44 } 45 } 46 //比较数字 47 int numCmp(int i, int j){ 48 return i - j; 49 } 50 static void showArray(int a[], int n){ 51 int i; 52 for(i = 0; i < n; i++){ 53 printf("%d ", a[i]); 54 } 55 } 56 57 int main(){ 58 int a[] = {20, 50, 30, 12, 22, 80, 100, 90, 88, 100, 12, 55, 12, 22, 35, 100}; 59 heapSort((void **)a, 16, (int (*)(const void *, const void *))numCmp); 60 showArray(a, 16); 61 getchar(); 62 }