1 #include "stdafx.h" 2 #include<stdio.h> 3 int h[101];//用来存放堆的数组 4 int n;//用来存储堆中元素的个数,也就是堆的大小 5 6 void swap(int x,int y){ 7 int temp = h[x]; 8 h[x] = h[y]; 9 h[y] = temp; 10 return; 11 } 12 13 //向下调整 14 void siftdown(int i){//传入一个向下调整的结点编号i,如果传入1就是从堆的顶点开始向下调整 15 int t, flag = 0;//flag用来标记是否继续向下调整 16 //当i结点有儿子(其实至少是有左二子)并且有需要继续调整的时候循环就执行 17 while (i*2<=n&&flag==0){ 18 //首先判断它和左二子的关系,并用t记录值较大的结点编号 19 if (h[i] < h[i * 2]){ 20 t = i * 2; 21 } 22 else t = i; 23 if (i * 2 + 1 <= n){ 24 if (h[t] < h[i * 2 + 1]){ 25 t = i * 2 + 1; 26 } 27 } 28 if (t != i){ 29 swap(t, i); 30 i = t;//更新i为刚才与它交换的儿子结点的编号,便于接下来继续向下调整 31 } 32 else 33 flag = 1;//否则说明当前的父节点已经比两个孩子结点都要大了,不需要再进行调整了 34 } 35 return; 36 } 37 //创建堆 38 void create() 39 { 40 int i; 41 //从最后一个非叶结点到第一个结点一次进行向上调整 42 for (i = n / 2; i >= 1; i--){ 43 siftdown(i); 44 } 45 return; 46 } 47 //堆排序 48 void heapsort(){ 49 while (n>1) 50 { 51 swap(1, n); 52 n--; 53 siftdown(1); 54 } 55 return; 56 } 57 58 int _tmain(int argc, _TCHAR* argv[]) 59 { 60 int i, num; 61 //读入n个数 62 scanf_s("%d",&num); 63 for (size_t i = 1; i < num; i++) 64 { 65 scanf_s("%d", &h[i]); 66 } 67 n = num; 68 //建堆 69 create(); 70 //堆排序 71 heapsort(); 72 //输出 73 for (size_t i = 1; i <= num; i++) 74 { 75 printf("%d ",h[i]); 76 } 77 getchar(); 78 getchar(); 79 return 0; 80 }