提到希尔排序,我们得先来看看插入排序,因为希尔排序本身就是对插入排序的一种优化。
插入排序的基本思想:每一步将一个待排序的元素,按其排序码的大小,插入到前面已经排好序的一组元素的合适位置上去,直到元素全部插完为止。
就像我们玩斗地主一样,接牌的时候,其实就是一种插入排序,每接一张牌,就会把牌放在自己手牌中合适的位置。
代码:
void Insert_Sort(int array[],int64_t size)
{
if(size <= 1){ //特殊情况处理,如果数组中的元素小于等于1,就直接返回,不需要排序
return;
}
int64_t bound = 1;
for(;bound < size;bound++){ //外层循环遍历整个数组
int bound_value = array[bound];
int64_t i = bound;
for(;i > 0;i--){ //内层循环进行排序操作
if(array[i-1] > bound_value){
array[i] = array[i-1];
}else{
break;
}
}
array[i] = bound_value; //这一步很重要,每一次循环,都要更新bound_value的值
}
}
下来,我们再说说希尔排序
希尔排序就是对插入排序的一种改进。因为如果元素集合在排序之前越接近有序,那么插入排序的效率越高。最优情况下,是
O(n^2)。
所以,希尔排序,就是让元素集合先做预排序,让元素集合接近有序,最后进行一次直接插入排序。
说到这,希尔排序就分为两步:
1.做预排序。
2.做插入排序。
void Shell_Sort(int array[],int64_t size)
{
if(size <= 1){
return;
}
int64_t gap = size/2;
for(;gap >= 1;gap /= 2){
int64_t bound = gap;
for(;bound < size;bound++){
int bound_value = array[bound];
int64_t i = bound;
for(;i >= gap;i-=gap){
if(array[i-gap] > bound_value){
Swap(&array[i],&array[i-gap]);
}else{
break;
}
}
array[i] = bound_value;
} //end for
} // end for
}