上一节写了自己怎么实现的插入排序中的直接插入排序,现在介绍一下自己对希尔排序的理解。
希尔排序的思路很简单,给定一个无序的数组,
首先是确定一个间隔d,d是用来对数组进行分组的,然后再对分组以后的每组数据进行组内排序,排序完成后在将d的值缩小,
然后再将数据按d进行分组,再对各个分组的数据进行排序
......
直至d=1,完成最后一次整个分组的排序,得到最后的结果即为排好序的数组。
本次分组d是按照数组的长度对折的方式来取的,
即,10个元素,第一次是d = (int)10/2=5,
第二次d=(int)5/2=2;
第三次是d=(int)2/2=1;
d=1是最后一次分组,则排序结束。
要注意的是:
1、本次交换使用的是传入数组地址的形式,因为数组元素之间的交换不可以用值传递,只能用地址传递,所以要注意。
2、对于排序,是改进了冒泡排序,将原来的相邻元素之间的比较改为相邻d个元素之间进行比较。d=1时即为冒泡排序。
希尔排序的主要代码如下:
#include <stdio.h>
#include <stdlib.h>
void swap(int* a,int* b)
{
int t;
t = *a;
*a = *b;
*b = t;
}
void FuncSort(int array[],int len,int d)
{
int i,j;
for(i=0;i<len-1;i++)
{
for(j=0;j<len-1-i;j++)
{
if(j+d <=len-1)
{
// printf("---------------------%d--------------j = %d----------d= %d-----\n",j,j+d,d);
if(array[j] > array[j+d])
{
//printf("需要交换第%d个元素%d和%d个元素%d\n",j+1,array[j],j+d+1,array[j+d]);
swap(&array[j],&array[j+d]);
}
//printf("\n");
}
}
}
}
void showList(int array[])
{
int i=0;
for(i=0;i<10;i++)
printf("%d ",array[i]);
}
int main()
{
int list[10]= {49,38,65,97,76,13,27,49,55,4};
int d=10,t;
int count=1;
for(t = (int)d/2;t>=1;t=t/2)
{
FuncSort(list,10,t);
//printf("第%d次排序结果:",count);
//showList(list);
//printf("\n");
count++;
}
showList(list);
return 0;
}
如果按照d=5,3,1的分组来进行,则会是下面的结果: