堆排是选择排序的一种,也就是首先选择一个值最大或最小的元素加到有序序列,
先了解一个堆这个结构:
如果拍好序列,逻辑视角就是顺序存储的完全二叉树,(大根)满足根结点的值大于左右结点的值
对所有的非终端节点(非叶子结点)进行处理(从数组最右端也就是逻辑结构的树的最下面的非终端结点(从上到下)处理)上代码
void HeadAjust(int a[],int k,int n){
a[0]=a[k]; //存起来此非叶子结点
for(int i=2*k;i<=n;i=i*2){ //找的此结点的左孩子结点
if(i<n&&a[i]<a[i+1]) //比较左右孩子结点的大小,i指向值大的
i++;
if(a[0]>=a[i]) break; //如果根节点大于左右孩子结点跳出完成此非终端节点的大根堆调正
else{ //要不然就把左右孩子值大的赋值给根
a[k]=a[i];
k=i; //并且让k指向i的位置等待下次循环比较此结点的孩子的孩子结点完成此结点之下的所有结点符合大根堆特性
}
}
a[k]=a[0]; //找出的位置赋值
}
void BuildDui(int a[],int n){
int i;
for(i=n/2;i>0;i--){ //首次建立大根堆
HeadAjust(a,i,n);}
}
void heapSort(int a[],int n){
BuildDui(a,n);
for(int i=n;i>1;i--){
wap(a[i],a[1]); //每次找出大根的值为树的根节点都和最后一个位置的结点交换位置
HeadAjust(a,1,i-1); //依次调整大根堆
}
}