堆排序

  堆排序过程:

  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 }

  

  

原文地址:https://www.cnblogs.com/ArtsCrafts/p/heap_sort.html