以下代码均是最大堆
/****************大根堆排序********************/
void AdjustDown(int *a,int s,int n)
{
a[0]=a[s];//a[0]暂时存放
for(int i=2*s;i<=n;i*=2)//沿着k较大的字节点向下筛选
{
if(i<n && a[i]<a[i+1])
i++;//取K较大的子节点的下标
if(a[0]>=a[i]) break;//筛选结束
else
{
a[s]=a[i];//将a[i]调整到双亲节点上
s=i;//修改k值,以便继续向下筛选
}
}
a[s]=a[0];//被筛选节点的值放在最终位置
}
void BuildMaxHeap(int *a,int n)
{
for(int i=n/2;i>0;i--)
AdjustDown(a,i,n);//向下调整
}
void HeapSort(int *a,int n)//n是指待排序列 的元素个数,数组a的长度是n+1,a[0]不使用
{
BuildMaxHeap(a,n);//创建大根堆,时间复杂度是o(n)
//调整大根堆,时间复杂度是o(nlgn)
for(int i=n;i>1;i--)
{
swap(a[1],a[i]);
AdjustDown(a,1,i-1);//向下调整
}
}
向最大堆插入元素,是指先将新节点放在堆的末尾,在对这个新的节点指向向上调整操作,代码如下
void AdjustUp(int *a,int key)//大根堆插入元素时,需要用到向上调整,key是向上调整的节点,也是堆的元素个数
{
a[0]=a[key];
int i=key/2;//若节点值大于双亲节点,则将双亲节点向下调,并继续向上比较
while(i>0 && a[i]<a[0])
{
a[key]=a[i];//双亲节点下调
key=i;
i=key/2;//继续向上比较
}
a[key]=a[0];//幅值到最终位置
}
利用大根堆求最小的K个数
//求最小的k个数
int a[n];//数组a中存放输入的N个数
int b[k+1];//从a中以此读入k个数a[0]...a[k-1],第一个数存在b[1]中,以此类推
BuildMaxHeap(b,k);//调整b为大根堆
for(int i=k;i<n;i++)
{
if(a[i]>b[1])
continue;
else
{
b[1]=a[i];
AdjustDown(b,1,k);
}
}
最小堆排序(可用于求最大的K个数)