
从堆的定义可以看出,堆实质是满足如下性质的完全二叉树,二叉树中任一非叶子结点均小于(大于)它的孩子结点



C语言代码实现
#include
#include
void HeapAdjust(int a[],int s,int m)//一次筛选的过程
{
int rc,j;
rc=a[s];
for(j=2*s;j<=m;j=j*2)//通过循环沿较大的孩子结点向下筛选
{
if(j<m&&a[j]<a[j+1]) j++;//j为较大的记录的下标
if(rc>a[j]) break;
a[s]=a[j];s=j;
}
a[s]=rc;//插入
}
void HeapSort(int a[],int n)
{
int temp,i,j;
for(i=n/2;i>0;i--)//通过循环初始化顶堆
{
HeapAdjust(a,i,n);
}
for(i=n;i>0;i--)
{
temp=a[1];
a[1]=a[i];
a[i]=temp;//将堆顶记录与未排序的最后一个记录交换
HeapAdjust(a,1,i-1);//重新调整为顶堆
}
}
int main()
{
int n,i;
scanf("%d",&n);
int a[n+1];
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
HeapSort(a,n);
}

若在输出堆顶的最小值(最大值)后,使得剩余n-1 个元素的序列重新建成一个堆,则得到n个元素的次小值(次大值)如此反复,便能得到一个有序序列,这个过程称为堆排序
(一)、如何在输出堆顶元素后,调整剩余元素为一个新的堆?
小根堆
堆的调整


从以上代码可以看出:对于一个无序序列反复筛选就可以得到一个堆即从一个无序序列建堆的过程就是一个反复筛选的过程
😛堆的建立
由于堆实质是一个线性表,那么我们可以顺序存储一个堆
例如:有关键字为49,38,65,97,76,13,27,49的一组记录,将其按关键字调整为一个小根堆


由以上分析知:
若一个无序序列建堆,然后输出根,重复该过程就可以由一个无序序列输出有序序列
实际上,堆排序就是利用完全二叉树中父结点与孩子结点之间的内在关系来排序的。
堆排序算法

算法性能分析:
