此排序算法完全是看着MoreWindows大神的博客一边看一边体会一边跟着敲出来的,在这里还是非常感谢他。
博客地址https://blog.csdn.net/MoreWindows/article/details/6709644
上述地址对堆排序讲的很细致,这里就不讲了。但是不知道为什么那篇博客中评论里会这么多人说有错误。
#include <stdio.h>
#include <Windows.h>
void Swap(int *a,int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
void Print(int a[],int n)
{
for( int i = 0 ; i < n ; ++i )
{
printf("%d ",a[i]);
}
printf("\n");
}
// 新加入i节点,其父节点为(i-1)/2
void MinHeapFixup(int a[] ,int i)
{
int j,temp;
temp = a[i];
j = (i - 1) / 2; //父节点
while( j >= 0 && i != 0 )
{
if(j >= 0 && i != 0)
{
break;
}
a[i] = temp;
i = j; //向父节点递归,当前这个i表示父节点
j = (i - 1) / 2;
}
a[i] = temp;
}
//堆的插入
void MinHeapAddNumber(int a[],int n,int nNum)
{
a[n] = nNum;
MinHeapFixup(a,n);
}
//调整堆
void MinHeapFixdown(int a[],int i,int n)
{
int j,temp;
temp = a[i];
j = 2 * i + 1;
while( j < n )
{
if( j + 1 < n && a[j + 1] < a[j] )
{
++j;
}
if( a[j] >= temp )
{
break;
}
a[i] = a[j];
i = j;
j = 2 * i + 1;
}
a[i] = temp;
}
//在最小堆中删除数
void MinHeapDeleteNumber( int a[],int n )
{
Swap( &a[0] ,&a[n - 1] );
MinHeapFixdown(a,0,n - 1);
Print(a,n);
}
//建立最小堆
void MakeMinHeap(int a[],int n)
{
//叶子节点不用排
for( int i = n / 2 - 1 ; i >= 0 ; --i)
{
MinHeapFixdown(a,i,n);
printf("下沉的节点%d. ",i);
Print(a,n);
}
}
void MinheapsortTodescendarray(int a[],int n)
{
MakeMinHeap(a,n);
for( int i = n ; i >= 1 ; --i )
{
MinHeapDeleteNumber(a,i);
}
}
int main()
{
int a[10] = {9,12,17,30,50,20,60,65,4,49};
MinheapsortTodescendarray(a,10);
for( int i = 0 ; i < 10 ; ++i )
{
printf("%d ",a[i]);
}
printf("\n");
system("pause");
return 0;
}
打印结果如下图,最小堆实现的降序排序