最大堆排序

堆排序(Heapsort)是指利用这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

通常堆是通过一维数组来实现的。在起始数组为 0 的情形中:

          父节点i的左子节点在位置 (2*i+1);

          父节点i的右子节点在位置 (2*i+2);

          子节点i的父节点在位置 floor((i-1)/2);

在堆的数据结构中,堆中的最大值总是位于根节点。堆中定义以下几种操作:

          最大堆调整(Max_Heapify):将堆的末端子结点作调整,使得子结点永远小于父结点

          创建最大堆(Build_Max_Heap):将堆所有数据重新排序

          堆排序(HeapSort):移除位在第一个数据的根结点,并做最大堆调整的递归运算

  1 #include <stdio.h>
  2 
  3 void SwapValue(int *OperatorA, int *OperatorB)
  4 {
  5     if ((NULL == OperatorA) || (NULL == OperatorB))
  6     {
  7         printf ("Invalid Parameter(s)!\n");
  8         return;
  9     }
 10 
 11     if ((*OperatorA) != (*OperatorB))
 12     {
 13         *OperatorA ^= *OperatorB;
 14         *OperatorB ^= *OperatorA;
 15         *OperatorA ^= *OperatorB;
 16     }
 17 }
 18 
 19 // 最大堆排序,升序
 20 // 向上调整成最大堆
 21 void MaxHeapFixUp(int *a, int l)
 22 {
 23     if ((NULL == a) || (l < 0))
 24     {
 25         printf ("Invalid Parameter(s)!\n");
 26         return;
 27     }
 28 
 29     int nTemp = a[l];
 30     int i = l;
 31     int j = (i - 1) / 2;
 32 
 33     while (j >= 0)
 34     {
 35         if (a[j] >= nTemp)
 36         {
 37             break;
 38         }
 39 
 40         a[i] = a[j];
 41         i = j;
 42         j = (i - 1) / 1;
 43     }
 44 
 45     a[i] = nTemp;
 46 }
 47 
 48 // 简化代码的向上调整
 49 void MaxHeapFixUp1(int *a, int l)
 50 {
 51     if ((NULL == a) || (l < 0))
 52     {
 53         printf ("Invalid Parameter(s)!\n");
 54         return;
 55     }
 56 
 57     int nTemp = a[l];
 58     int i;
 59     int j;
 60     
 61     for (i = l, j = (i - 1) / 2; (j >= 0) && (a[j] < nTemp); i = j, j = (i - 1) / 2)
 62     {
 63         SwapValue (&a[i], &a[j]);
 64     }
 65 }
 66 
 67 // 向下调整
 68 void MaxHeapFixDown(int *a, int l, int N)
 69 {
 70     if ((NULL == a) || (l < 0) || (l >= N))
 71     {
 72         printf ("Invalid Parameter(s)!\n");
 73         return;
 74     }
 75 
 76     int nTemp = a[l];
 77     int i = l;
 78     int j = 2 * i + 1;
 79 
 80     while (j < N)
 81     {
 82         if (((j + 1) < N) && (a[j+1] > a[j]))
 83         {
 84             ++j;
 85         }
 86 
 87         if (a[j] <= nTemp)
 88         {
 89             break;
 90         }
 91 
 92         a[i] = a[j];
 93         i = j;
 94         j = 2 * i + 1;
 95     }
 96 
 97     a[i] = nTemp;
 98 }
 99 
100 // 将数组转换成最大堆存储
101 void ShiftToMaxHeap(int *a, int N)
102 {
103     if ((NULL == a) || (N <= 0))
104     {
105         printf ("Invalid Parameter(s)!\n");
106         return;
107     }
108 
109     for (int i = N / 2 - 1; i >= 0; --i)
110     {
111         MaxHeapFixDown (a, i, N);
112     }
113 }
114 
115 // 最大堆排序
116 void MaxHeapSort(int *a, int N)
117 {
118     if ((NULL == a) || (N <= 0))
119     {
120         printf ("Invalid Parameter(s)!\n");
121         return;
122     }
123 
124     for (int i = N - 1; i >= 1; --i)
125     {
126         SwapValue (&a[0], &a[i]);
127         MaxHeapFixDown (a, 0, i);
128     }
129 }
130 
131 int main(void)
132 {
133     int a1[9] = {9, 8, 7, 6, 5, 4, 3, 2, 1};
134 
135     MaxHeapSort (a1, 9);
136 
137     for (int i = 0; i < 9; ++i)
138     {
139         printf ("%d ", a1[i]);
140     }
141 
142     printf ("\n");
143 
144     return 0;
145 }

原文地址:https://www.cnblogs.com/ldjhust/p/2986497.html