所属专栏:C++初阶
一、什么是希尔排序?
希尔排序是一种先进行预排序(以达到接近于有序的状态),然后最后进行整体排序
1.1如何进行预排序呢?
如下图
这里分为gap组,然后每一组进行排序,这就是所谓的预排序
1.1.1两个数字进行预排序时
void ShellSort(int* a, int n,int x)
{
int gap;
int end;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end] = a[end + gap];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
1.1.2多个数字进行预排序时
法一:
void ShellSort(int* a, int n,int x)
{
int i = 0;
int j;
int gap;
for (i = 0; i < gap; i++)//gap组
{
for (j = i; i < n; j += gap)//每个gap组进行排序
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end+gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
法二:
void ShellSort(int* a, int n,int x)
{
int i = 0;
int gap;
for (; i < n-gap; i += gap)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end+gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
1.2整体变gap排序使得整个数组有序
这里每次减小gap的值每一次进行预排序使得整个数组趋于有序,直到gap=1时相当于插入排序,此时因为已经趋于有序了,所以插入排序所用的时间非常少,效率很高
void ShellSort(int* a, int n,int x)
{
int i = 0;
int gap;
while (gap >= 1)
{
gap /= n / 3 + 1;
for (; i < n - gap; i += gap)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end] = a[end + gap];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
二、希尔排序的实现
经过某位大佬的计算gap的值除以3效率非常高
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void ShellSort(int* a, int n)
{
int i = 0;
int gap = n / 3 + 1;
while (gap > 1)
{
gap = gap / 3 + 1;
for (i = 0; i < n - gap; i ++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end+gap] = a[end];
end -= gap;
}
else
{
break;
}
}
a[end + gap] = tmp;
}
}
}
int main()
{
int i;
int a[] = { 1,5,6,2,3,0,9,4,8,7 };
ShellSort(a, sizeof(a) / sizeof(int));
for (i = 0; i < sizeof(a) / sizeof(int); i++)
printf("%d ", a[i]);
return 0;
}