一、
主函数:void Hea_Sort(int* head,int low,int high,int Step_L,int Bool)
参数解释
head:数组指针
[low, high]:需排序的数组范围
Step_L:需排序步长
Bool:等于1表示从小到大排序,不等于1从大到小排序
主函数引用:void Hea_Adjust(int* head,int high,int Start,int Step_L,int Bool)
参数解释
head:数组指针
Start:需调整的位置
high:数组中能够进行调整的最高位置
Step_L:需排序步长
Bool:等于1表示从小到大排序,不等于1从大到小排序
说明
Step_L=1时
第一步对下标low+{0,1,2,3,4,5…}排序
Step_L=2时
第一步对下标low+{0,2,4,6,8,10…}排序
Step_L=3时
第一步对下标low+{0,3,6,9,12,15…}排序
以此类推
#include <stdio.h>
#include <time.h>
void Hea_Sort(int* head,int low,int high,int Step_L,int Bool);
void Hea_Adjust(int* head,int high,int Start,int Step_L,int Bool);
//堆排序
//需排序数组中第1个元素的位置为low
//需排序数组中第i个元素的位置为low+i*Step_L
//需排序数组中调整的开始位置为(L-1)/2(逻辑位置),low+(L-1)/2*Step_L(实际地址)
void Hea_Sort(int* head,int low,int high,int Step_L,int Bool){
//创建根堆
int Shigh=low+(((high-low+1)/Step_L)-1+(((high-low+1)%Step_L)!=0))*Step_L;//需排序的最后一个数的下标
int L=(Shigh-low)/Step_L+1;//需排序数组长度
int Start=low+(L/2-1)*Step_L;//Start为需调整位
while(Start>=low){
Hea_Adjust(head,high,Start,Step_L,Bool);
Start-=Step_L;
}
printf("\n%d ",head[low]);//输出大根堆或小根堆的low处的最值
//调整根堆
head[low]=head[high];//将high处数据放到low处
Start=low;//此时,已经是小根堆或大根堆,上一步使得仅有low处数据需要调整,于是将Start置为low
high-=Step_L;//需调整的位置
while(low<=high){
Hea_Adjust(head,high,Start,Step_L,Bool);
printf("%d ",head[low]);//输出大根堆或小根堆的最值
head[low]=head[high];//将high处数据放到low处
high-=Step_L;//能够进行调整的最高位置
}
}
//调整函数,为上面堆排序所用
//Bool=1,小堆;Bool=0,大堆
void Hea_Adjust(int* head,int high,int Start,int Step_L,int Bool){
int Left=Start+(Start+1)*Step_L;//左子
int Right=Start+(Start+2)*Step_L;//右子
int temp;//交换
while(Left<=high){//左子存在,需要判断是否调整
if(Right<=high){//一父二子比较:Start、Left、Right
//简化可用(((head[Start]-head[Left])*(head[Start]-head[Right])<=0) || (((head[Start]>head[Left])==Bool) && ((head[Start]>head[Right])==Bool)))
if(Bool){//小堆,与双子中最小的交换
if(head[Start]>=head[Left] || head[Start]>=head[Right]){//选择交换子
if(head[Left]<=head[Right]){//选择左交换子
temp=head[Start];
head[Start]=head[Left];
head[Left]=temp;
Start=Left;//下一步需调整的位置
}else{//选择右交换子
temp=head[Start];
head[Start]=head[Right];
head[Right]=temp;
Start=Right;//下一步需调整的位置
}
}
else{
break;
}
}
else{//大堆,与双子中最大的交换
if((head[Start]<=head[Left] || head[Start]<=head[Right])){//选择交换子
if(head[Left]>=head[Right]){//选择左交换子
temp=head[Start];
head[Start]=head[Left];
head[Left]=temp;
Start=Left;//下一步需调整的位置
}else{//选择右交换子
temp=head[Start];
head[Start]=head[Right];
head[Right]=temp;
Start=Right;//下一步需调整的位置
}
}
else{
break;
}
}
}
else{//一父一子比较:Start、Left
if(head[Start]>=head[Left]==Bool){//2021.10.09因为这里的”==”符号用了两小时寻找!!!
temp=head[Start];
head[Start]=head[Left];
head[Left]=temp;
Start=Left;//下一步需调整的位置
}
else{
break;
}
}
Left=Start+(Start+1)*Step_L;//更新左子
Right=Start+(Start+2)*Step_L;//更新右子
}
}
int main(int argc, char **argv) {
printf("Hello, World!\n");
int s[5];
s[0]=2;
s[1]=5;
s[2]=1;
s[3]=4;
s[4]=3;
int i=0;
while(i<5)printf("%d ",s[i++]);
printf("\n---------\n");
Hea_Sort(s,0,4,1,0);
return 0;
}