堆排序的思想:根据堆的定义,堆的根节点不是最大值就是最小值(最大堆或最小堆),通过每次拿走根节点,然后再重新对堆进行调整,就能保证拿走的序列顺序是按从小到大或是从大到小排列的。每次拿走根节点,堆的节点数就减一,取最后一个叶子节点代替根节点,调整堆。直到堆的节点数量为1。
最大堆
堆调整:
void adjust_heap(int a[],int hole,int n)
{
int left=2*hole+1;
int t;
while(left<n-1){ // hole含有左右孩子,并交换hole和孩子当中的较大的节点
if(a[left]<a[left+1])
left++;
if(a[hole]<a[left]){
t=a[hole];
a[hole]=a[left];
a[left]=t;
hole=left;
left=2*hole+1;}
else
return;
}
if(left==n-1){ //hole只有左孩子
if(a[hole]<a[left]){
t=a[hole];
a[hole]=a[left];
a[left]=t;
hole=left;}
else
return;
}
return ;
}
堆的建立:
void built_heap(int a[],int n)
{
if(n==0||n==1) return;
for(int i=(n-2)/2;i>=0;i--) //从第一个不是叶子节点开始,从下往上调整。
adjust_heap(a,i,n);
}
堆排序:
void heap_sort(int a[],int n)
{
int m;
for(int i=0;i<n;i++) //每次拿走根节点,然后是倒数第一个节点赋给根节点,节点总数少一
{
adjust_heap(a,0,n-i);
m=a[0];
a[0]=a[n-i-1];
a[n-i-1]=m;
}
}
int main()
{
int a[]={12,42,122,-90,-32,25,21,14};
built_heap(a,8);
heap_sort(a,8);
for(int i=0;i<8;i++)
cout<<a[i]<<" ";
while(1);
return 0;
}