堆排序分析(大根堆为例,由小到大排序)
作者:互联网
时间复杂度为O(nlogn),思路就是从最后一个非叶结点开始,依次往回遍历每个结点,将以该结点为根的子树建立成大根堆,直到遍历到整棵完全二叉树的根结点时为止,此时整棵树为大根堆。
以当前结点为根的子树建立大根堆:
//向下调整,将该结点的子树变成大根堆
void AdjustDown(int A[],int k,int len){ //k为根结点编号,len为数组长度
int i,j;
A[0]=A[k];
for(j=2*k;j<=len;j*=2){
if(j<len&&A[j]<A[j+1]) //右孩子较大
j++;
if(A[0]<A[j]){
A[k]=A[j];
k=j;
}
else break;
}
A[k]=A[0];
}
堆排序算法:
//堆排序算法
void HeapSort(int A[],int len){
int i,temp;
for(i=len/2;i>=1;i--) //建立初始大根堆
AdjustDown(A[],i,len); //从len/2到1,反复调整堆
for(i=len;i>1;i--){
temp=A[1];
A[1]=A[i];
A[i]=temp; //把最大的元素放到了最后面,最终排序结果为由小到大
AdjustDown(A[],1,i-1); //把剩余i-1个元素整理成堆
}
}
这样排序的结果为由小到大!
如果插入元素的话,直接插入到最后的位置,然后将插入的元素向上调整,直到整棵树再次变成大根堆时为止!
向上调整的代码:
//插入元素到最后位置,需要向上调整建立大根堆
void AdjustUp(int A[],int len){
A[0]=A[len];
int i=len/2,j=len;
while(i>0&&A[i]<A[0]){
A[j]=A[i]; //双亲结点下调
j=i;
i/=2; //继续向上比较
}
A[j]=A[0];
}
标签:大根堆,结点,为例,int,堆排序,len,为根 来源: https://blog.csdn.net/KK_2018/article/details/110377395