关于希尔排序看看百度百科的定义
下面看看C代码的实现
#define EXCHANGE(num1, num2) { num1 = num1 ^ num2; num2 = num1 ^ num2; num1 = num1 ^ num2;}
void shellSort( int num[], int count )
{
int gap, i, j;
for( gap = count / 2; gap >0; gap = gap / 2 ) //拆分整个序列,元素间距为gap(也就是增量)
{
for( i = gap ; i < count; i++ ) //对子序列进行直接插入排序
{
for( j = i - gap; j >= 0 && num[j] > num[j + gap]; j = j - gap )
{
EXCHANGE( num[j], num[j + gap] );
}
}
}
}
下面分析一下代码执行过程
这是原始数组,第一次元素间距 gap 的值为数组数量的一半,gap=5,下来比较num[0]和num[5]的大小,0<3不需要交换,下来继续比较num[1]和num[6]的大小,8>7交换两个数字位置
下来比较1和9,不需要交换,继续比较5和2,5>2要交换两个数的位置
下来比较4和6,不需要交换位置,数组已经比较结束了,下来元素间距减小为原来的一半,gap=5,它的一半为2.5但是程序取的是整数,所以元素间距gap的值变为2.
下来继续比较num[0]和num[2],0<1,不需要交换位置,继续比较7和2,7>2需要交换位置。
下来比较1和4,不需要交换位置。继续比较7和3,需要交换位置。
这样依次往下比较8和5交换位置
9和6交换位置
9和6交换位置后,已经比较到了数组最后一位,但是此时还不能结束,因为数组前面的数据发生了变化,所以要在向前比较,
此时元素间距为2,所以6要它前面间距一个数字的7比较,前面的数大于后面的数需要交换一次位置,于是6和7在交换一次位置。
下来6继续和前面的3比较,不需要交换,4和1比不需要交换,3和2比不需要交换,1和0比也不需要交换。此时这趟比较完成。
下来元素间距减小为原来的一半,2的一半是1,所以gap变为1,此时相邻两个元素比较。
0和2不需要交换,2和1需要交换。
5和6需要交换
这样共交换9次位置之后,数组排序结束。
下面测试一下最坏情况下,需要交换的次数
最坏情况下需要交换13次。
下来再看看最好情况下需要交换几次。
最好情况下交换0次。
下面测试一下随机生成10000个数据,需要交换的次数和执行时间。
下面用一张动图来演示一下排序的过程