概述:
希尔排序(Shell’sSort)又称“缩小增量排序”,是一种属插入排序类的方法,但在时间效率上比直接插入排序徐和折半插入排序等有较大的改进。
希尔排序的基本思想是先将整个待排记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再对全体记录进行一次直接插人排序。
一般情况下,先选定step=length/2作为第一增量,然后将距离为step的所有元素分到一组,并对每一组的元素进行直接插入排序。然后再取step/2作为第二增量,重复上述操作。
当增量step减到1时,整个序列被分到一组,然后进行一次直接插入排序,至此希尔排序结束希尔排序的一个特点是:子序列的构成不是简单的“逐段分割”,而是将相隔某个“增量”的记录组成一个子序列。
希尔排序函数:
直接插入排序请参考:(点击这里)
void ShellSort(int array[],int length){
for(int step=length/2;step>0;step=step/2){//初始步长step为length/2
for(int i=0;i<step;i++){ //遍历每一次分组后的第一个元素
for(int j=i+step;j<length;j+=step){ //遍历步长为step的所有元素 ,进行直接插入排序
int temp=array[j];
int m=j-step;
for(m=j-step;m>=0&&array[m]>temp;m-=step){//array[m]小于 temp 时循环结束,结束后应将 temp 赋值给a[m+step]
array[m+step]=array[m]; //只要array[m]比temp大,就将此数后移一位(此处是step位)
}
array[m+step]=temp; //将 temp 赋值给a[m+step]
}
}
}
}
完整代码:
//希尔排序
#include <iostream>
using namespace std;
void Print(int array[],int length){ //每执行一次打印一次序列
for(int i=0;i<length;i++){
cout<<array[i]<<" ";
}
cout<<endl;
}
void ShellSort(int array[],int length){
for(int step=length/2;step>0;step=step/2){//初始步长step为length/2
for(int i=0;i<step;i++){ //遍历每一次分组后的第一个元素
for(int j=i+step;j<length;j+=step){ //遍历步长为step的所有元素 ,进行直接插入排序
int temp=array[j];
int m=j-step;
for(m=j-step;m>=0&&array[m]>temp;m-=step){//array[m]小于 temp 时循环结束,结束后应将 temp 赋值给a[m+step]
array[m+step]=array[m];
}
array[m+step]=temp; //将 temp 赋值给a[m+step]
}
}
Print(array,length); //每排序一趟就打印一次序列
}
}
int main(){
int array[]={49,38,65,97,76,13,27,49};
int length=sizeof(array)/sizeof(*array);
Print(array,length); //先打印原始序列
ShellSort(array,length);
return 0;
}
运行示例如图:
第一行为原始序列;第二、三、四行分别为经过第一趟、第二趟、第三趟希尔排序的结果。