希尔排序通过将比较的全部元素分为几个区域来提升插入排序的性能。这样可以让一个元素可以一次性地朝最终位置前进一大步。然后算法再取越来越小的步长进行排序,算法的最后一步就是普通的插入排序,但是到了这步,需排序的数据几乎是已排好的了(此时插入排序较快)。
希尔排序的具体细节:
step 1 对序列进行分组,组数为原组数的C分之一(这里取C为2),初始当成组数为序列长度,即每个数字算一个组。
step 2 对分组后的序列采用插入排序。
goto step 1
希尔排序的实现如下:
shellsort_original是最直观的实现,代码不够精简。
shellsort_improved是优化之后的实现,省了一个for循环,在对分组进行插入排序的时候,并不是排完一组再排下一组,而是根据数组的索引,索引指到哪个数就排哪个数所在的组。
#include "iostream"
using namespace std;
void shellsort_original(int ary[],int len){
//算法开始
for(int i =len / 2; i != 0;i = i/2){//步长确定
cout<<i<<endl;
for (int j =0;j < i;++j)
{
for (int k = i + j;k < len;k = k + i)
{
if (ary[k] < ary[k - i])
{
int l = k - i;
int tmp = ary[k];
while (ary[l] > tmp&&l >= 0)
{
ary[l+i] = ary[l];
l -= i;
}
ary[l+i] = tmp;
}
}
}
}
//算法结束
}
void shellsort_improved(int ary[],int len)
{
for(int i =len / 2; i != 0;i = i/2){//i为步长
for(int j = 1 + i; j < len;++j){
if (ary[j] < ary[j - i])
{
int l = j - i;
int tmp = ary[j];
while (ary[l] > tmp&&l >= 0)
{
ary[l+i] = ary[l];
l -= i;
}
ary[l+i] = tmp;
}
}
}
}
int main(int argc, char *args[])
{
#define KLEN 10
int ary[KLEN]={1,5,7,2,4,8,2,9,3,6};
void (*shellsort)(int ary[],int len);
shellsort = shellsort_improved;
for (int i=0;i <KLEN;i++)
{
cout<<ary[i]<<endl;
}
cout<<"==========>"<<endl;
shellsort(ary,KLEN);
cout<<"==========>"<<endl;
for (int i =0;i < KLEN;i++)
{
cout<<ary[i]<<endl;
}
system("pause");
return 0;
}