思想:
复杂度:
O(logN)
O(N)
堆的性质:
1: 堆中某个节点的值总是不大于或不小于其父节点的值;
2: 堆总是一棵完全二叉树。
堆分类为:大顶堆和小顶堆
解析:
第一步:建堆(举例大顶堆)
从父节点9开始从左往右,与左右孩子相比较,寻找比自己大的数,进行交换;
第二步:排序
将顶节点与尾节点交换, 尾节点的值切下来,放在后面作为已排好的结果;
再对剩余的堆值,进行建堆维护,得出第一轮排序结果;
重复以上操作;
完整代码
#include <stdio.h> void PrintSort(int * a, int n) { printf(" "); int i = 0; for(i=0; i<n; i++) { printf(" %d ", a[i]); } printf(" "); } void swap(int * a, int * b) { int t = *a; *a = *b; *b = t; } /* a:数组 n:数组长度 i:下标 */ void heapify(int *a, int n, int i) { // 找最大的值 int largest = i; int lson = i*2+1; int rson = i*2+2; if (lson < n && a[largest] < a[lson]) largest = lson; if (rson < n && a[largest] < a[rson]) largest = rson; // 父节点不是最大的, 有个孩子比它大 if (largest != i) { swap(&a[largest], &a[i]); // 维护当前堆的性质 heapify(a, n, largest); } } void HeapSort(int *a, int n) { // 建堆 int i; for (i=n/2-1; i>=0; i--) { heapify(a, n, i); } // 注释 printf("建堆的结果:"); PrintSort(a, n); // 排序 printf("排序的过程:"); for(i=n-1; i>0; i--) { swap(&a[i], &a[0]); // 维护剩余(堆顶)元素的性质 heapify(a, i, 0); PrintSort(a, n); } } void main() { int n = 8; int a[] = {9, 2, 1, 3, 8, 4, 7, 6}; HeapSort(a, n); printf("排序结果: "); PrintSort(a, n); }