堆排序定义:
k表示相应序列,i表示相应的下标
k(i)<=k(2*i)且k(i)<=k(2*i+1) (i=1..2..n/2)且有2i+1<=n
算法分析:
其实给定一个序列,那么相应我们逻辑上就可以就其理解为满二叉树.
1.将对应序列组织成满二叉树
2.逐步满足二叉树中的堆定义!
提示:在逐步满足二叉树堆条件定义过程中,我们要做的就是利用二叉树的性质,将其子树一步步满足二叉树的堆的定义,那么最终整棵树
也会满足相应堆的定义!
半天努力哈,堆排序终于出炉了:
void HeapSortChild(int B[],int n,int len){
int i;
int j=2*n;
while(j<=len){
if(j+1<=len)
i=(B[j]>B[j+1])?j+1:j;
else
i=j;
if(B[i]<B[n]){
int temp=B[i];
B[i]=B[n];
B[n]=temp;
n=i;
j=2*i;
}
else
break;
}
}
void HeapSort(int A[],int len){
int *B=(int *)malloc(sizeof(int)*len+1);
for(int i=0;i<len;i++){
B[i+1]=A[i];
}
for(int j=len/2;j>=1;j--){
HeapSortChild(B,j,len);
}
for(i=len;i>=2;i--){ 注意此处,精华所在,第一次堆排序找出了最小的一个数,此时的堆架构出来了
//以后每一次只需要找出下一个最小的数就是了
int temp=B[i];
B[i]=B[1];
B[1]=temp;
HeapSortChild(B,1,i-1);
}
for(i=0;i<len;i++){
A[i]=B[i+1];
}
}
void print(int A[],int len){
int i=0;
for(i=0;i<len;i++)
cout<<A[i]<<" ";
cout<<endl;
}
void main(){
int A[15]={12,3,4,6,98,123,3,56,78,11,65,455,324,0,1};
print(A,15);
//BinarySort(A,15);
HeapSort(A,15);
//HeapSortData(A,15);
print(A,15);
}
推而广之:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆。
根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆。
------------------------------------------------------------------------------------------------------
算法分析:
HeapSortChild时间效率分析:Min=a*1 Max=b*lg len;
那么加入外层循环的话Min=len/2*a+(len-1)*a Max=len/2*b*lg len+(len-1)*b*lg len
那么大概可以推出O(n)=len*lg len=O(nlg n)