什么是希尔排序
希尔排序有时也叫缩小增量排序,所以,希尔排序法又称缩小增量法。
希尔排序法的基本思想:
首先确定好一个整数gap,把待排序文件中所有数据分成若干个组,所有距离(间距)为gap的数据分在同一组内,对每一组的数据进行直接插入排序。然后,取更小的gap,重复上述的分组和排序,最后,当gap等于1的时候,所有数据就排好序了。
希尔排序法思想图解:
第一趟排序(gap = 5)代码
void ShellSort(int* a, int n)
{
int gap = 5;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int x = a[end + gap];
while (end >= 0)
{
if (a[end] > x)
{
a[end + gap] = a[end];
end = end-gap;
}
else
{
break;
}
}
a[end + gap] = x;
}
}
接下来我们只需要控制gap这个变量,经过若干组预排序之后,gap = 1,即可完成希尔排序。
但是,gap 一般要设多大的值呢?
通常,如果数组元素个数是n个,令gap = n,初始的gap一般会设置为gap/2,
当然,这是由程序员决定的,也可以是gap/3,等等其他的数,
不过有一个点需要注意,比如gap/3,每次除3的时候要+1,不然可能会出现gap取不到1的情况。
希尔排序代码
void ShellSort(int* a, int n)
{
//多次预排序gap>1 + 直接插入排序gap =1
int gap = n;
while (gap > 1)
{
gap = gap / 2;
for (int i = 0; i < n - gap; i++)
{
int end = i;
int x = a[end + gap];
while (end >= 0)
{
if (a[end] > x)
{
a[end + gap] = a[end];
end = end - gap;
}
else
{
break;
}
}
a[end + gap] = x;
}
}
}
希尔排序特性总结
1、希尔排序是对直接插入排序的优化算法。
2、当分组间距gap >1 时,进行的都是预排序,预排序的目的是让数组更接近于有序。
当gap == 1 时,数组已经接近有序了,此时进行直接插入排序就非常快了。
3、时间复杂度分析:
最好的情况下,数组有序,所以时间复杂度为O(N)。
最坏的情况就是(1+2+3+…+N/gap)* gap。
gap越大,预排序就越快,预排序之后就越不接近有序。
gap越小,预排序越慢,预排序之后越接近有序。
当 int gap = N(N个数) 每次取 gap = gap/2 时,可以算出 一共进行了logN(2为底)次预排序,每次预排序操作了接近N次,所以时间复杂度大致为 O(logN*N)。
4、稳定性:希尔排序是不稳定的排序。