#include<stdio.h>
#include<algorithm>
int A[10000000];
using namespace std;
inline int PARENT(int i)
{
return i>>1;//return i/2;
}
inline int LEFT(int i)
{
return i<<1;//i*2
}
inline int RIGHT(int i)
{
return (i<<1)+1;//i*2+1
}
//调用前,根结点为LEFT(i)和RIGHT(i)的子树都是最大堆,但i有可能小于其孩子。
//调整A[i]的位置
//以下为MAX_HEAPIFY的三个版本
void MAX_HEAPIFY_recursion(int A[],int i,int heapsize)
{//T(n)<=T(2n/3)+O(1)
int left=LEFT(i),right=RIGHT(i),largest;
if(left<=heapsize&&A[left]>A[i]) largest=left;
else largest=i;
if(right<=heapsize&&A[right]>A[largest]) largest=right;
if(largest!=i){
swap(A[i],A[largest]);//交换后,A[largest]可能违反最大堆的性质,再次调整
MAX_HEAPIFY_recursion(A,largest,heapsize);
}
}
void MAX_HEAPIFY_loop(int A[],int i,int heapsize)
{
while(1){
int left=LEFT(i),right=RIGHT(i),largest;
if(left<=heapsize&&A[left]>A[i]) largest=left;
else largest=i;
if(right<=heapsize&&A[right]>A[largest]) largest=right;
if(largest!=i){
swap(A[i],A[largest]);i=largest;
} else break;
}
}
void MAX_HEAPIFY_loop1(int A[],int adjust,int heapsize)
{
int adjustkey=A[adjust];//要调整的结点值
for(int largerson=LEFT(adjust);largerson<=heapsize;largerson=LEFT(adjust)){
if(largerson<heapsize&&A[largerson]<A[largerson+1]) largerson++;//寻找较大子结点
if(adjustkey>A[largerson]) break;//不再向下沉
A[adjust]=A[largerson];adjust=largerson;
//逐级下沉。adjust:当前要调整的结点值。largerson:它的大儿子
}
A[adjust]=adjustkey;//到它应到的位置
}
void BUILD_MAX_HEAP(int A[],int n)
{/*将无序数组建成最大堆,before each "for" iteration,
i+1,i+2,...,n都是一个最大堆的根结点*/
for(int i=n/2;i>=1;i--) MAX_HEAPIFY_recursion(A,i,n);
//for(int i=1;i<=n;i++) printf("%d ",A[i]);putchar('\n');
}
void HEAPSORT(int A[],int n)
{
BUILD_MAX_HEAP(A,n);
for(int i=n;i>=2;i--){
swap(A[1],A[i]);//最大元素放最后
MAX_HEAPIFY_recursion(A,1,i-1);//i-1:heapsize
//for(int i=1;i<=n;i++) printf("%d ",A[i]);putchar('\n');
}
}
int main(void)
{
//freopen("1.txt","r",stdin);
//freopen("2.txt","w",stdout);
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",A+i);
HEAPSORT(A,n);
for(int i=1;i<=n;i++) printf("%d ",A[i]);
return 0;
}
heapsort堆排序
最新推荐文章于 2020-03-21 14:12:54 发布