希尔(Shell)排序
设立增量gap,按gap移动下标,然后从后往前进行比较;持续缩小gap,直至gap=1。
增量序列中的值没有除1以外的公因子(素数),并且最后一个增量值必须等于1。
类似于直接插入排序。
- 从小到大进行排序
- 时间复杂度O( n^1.3 ~ 1.5^ )
- 空间复杂度O(1),不稳定
1. 图解希尔排序
- 定义增量序列,按增量从大到小,对数组进行排序,直至增量为1。
- 1、遍历数组, arr[i] 从第二个数字到最后一个数字。
- 2、首先定义 tmp 保存 arr[i] 的值,避免数字移动将 arr[i] 的值覆盖。
- 3、从后往前,将 i 下标的值(即 tmp)和位于 i 之前(即下标 0 ~ (i-gap) )的数字 arr[j] 进行比较。(移动幅度为gap)
- 4、如果下标 j 的值 arr[j] 大于 tmp ,将该数字 arr[j] 向后移动一位到 j+gap
- 5、如果找到某一位下标 j 的值 arr[j] 小于等于 tmp 的值 ,则跳出循环
- 6、将 tmp 赋给 j 的后一位 arr[j+gap],完成交换。
增量gap = 3
增量gap = 1
2. C语言实现
void Shell(int* arr, int len, int gap)
{
int i;
int j;
int tmp;
for (i = gap; i < len; i++)
{
tmp = arr[i];
for (j = i - gap; j >= 0; j -= gap)
{
if (arr[j] <= tmp)
{
break;
}
else
{
arr[j + gap] = arr[j];
}
}
arr[j + gap] = tmp;
}
}
void ShellSort(int* arr, int len)
{
int d[] = {5,3,1};
for (int i = 0; i < sizeof(d)/sizeof(d[0]); i++)
{
Shell(arr, len, d[i]);
}
}