堆的定义:
设一个非叶子节点的下标为n;
孩子节点下标分别为2n+1,2n+2;
a[n]>a[2n+1]&&a[n]>a[2n+2],是大根堆;
a[n]<a[2n+1]&&a[n]<a[2n+2]是小根堆。
堆排序的思路:最后一个非叶子节点的下标为(size/2)-1;从最后一个非叶子节点开始往前调整数组,使之成为堆<1>,所以需要一个函数来初始化堆;在往前调整的过程中要注意,节点与其l或r节点互换的过程中,以l或r的节点作为n的节点也要满足堆的性质,所以需要一个函数从上至下来调整堆。初始化完成后,交换堆顶元素与当前的末尾元素,使当前的最值调整到最后边。
附上代码:
# include<iostream>
using namespace std;
int MAX(int a ,int b)
{
return a>b?a:b;
}
void swap(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
void Heapfromtop(int a[],int j,int size)
{
int jl,jr,max;
while(j<=(size)/2-1)
{
jl=2*j+1;
jr=2*j+2;
if(jr>size-1)
{
if(MAX(a[jl],a[j])!=a[j])
{
swap(a[jl],a[j]);
break;
}
else
{
break;
}
}
else
{
if((max=MAX(MAX(a[j],a[jl]),a[jr]))!=a[j])
{
if(max==a[jr])
{
swap(a[j],a[jr]);
j=jr;
}
else
{
swap(a[j],a[jl]);
j=jl;
}
}
else
{
break;
}
}
}
}
void Init_heap(int a[],int size)
{
int max;
for(int i=size/2-1;i>=0;i--)
{
int l=i*2+1;
int r=i*2+2;
if(r>size-1)
{
if(MAX(a[l],a[i])!=a[i])
{
swap(a[l],a[i]);
}
}
else
{
if((max=MAX(MAX(a[i],a[l]),a[r]))!=a[i])
{
if(max==a[l])
{
swap(a[i],a[l]);
Heapfromtop(a,l,size);
}
else
{
swap(a[i],a[r]);
Heapfromtop(a,r,size);
}
}
}
}
}
void main()
{
int a[10]={1,9,2,8,3,4,7,5,0,6};
Init_heap(a,10);
for(int i=10-1;i>=0;i--)
{
swap(a[0],a[i]);
Heapfromtop(a,0,i);
}
cout<<"heap sort done:\n";
for(int j=0;j<10;j++)
{
cout<<a[j]<<" ";
}
return;
}