简述
希尔排序(Shell Sort )是 D .L.希尔(D.L.Shell)提出的 "缩小增量" 的排序方法。它的作法不是每次一个元素挨一个元素的比较,而是初期选用大跨步(增量较大)间隔比较,使记录跳跃式接近它的排序位置;然后增量缩小,最后增量为 1 。这样记录移动次数大大减少,提高了排序效率。希尔排序对增量序列的选择没有严格规定。
算法思路
1.先取一个正整数 d1(d1 < n) ,把全部记录分成 d1个组,所有距离为 d1的倍数的记录看成一组,然后在各组内进行插入排序;
2.然后取 d2( d2 < d1 ) ;
3.重复上述分组和排序操作,直到取 di = 1(i >= 1) ,即所有记录成为一个组为止。一般选 d1约为 n/2 , d2为 d1 / 2 , d3为 d2 / 2 ,…, d i = 1 ;
代码
#include <QDebug>
#include <QApplication>
void mDebug(int a[], int len)
{
QString str;
for (int i = 0; i < len; i++)
{
str += QString("%1 ").arg(a[i]);
}
qDebug() << str;
}
template<class T>
void ShellSort(T a[],int len)
{
// k值代表前文中的增量
int k = len / 2;
// 方法一
// 当增量k值变化到0,结束循环……
while(k >= 1)
{
// i从k开始每次+1,a[i]与a[i-k]比较
for(int i = k; i <= len; i++)
{
// 当a[i]小于a[i-k]时,则需要记住当前a[i]的值,这样有利于只用交换一遍
if (a[i] < a[i - k])
{
int j = i;
T temp = a[j];
do
{
a[j] = a[j - k];
j -= k;
}while(j - k >= 0 && temp < a[j - k]);
a[j] = temp;
}
}
// 计算下一轮步长
k = k / 2;
}
// // 方法二
// // 当增量k值变化到0,结束循环……
// while (k >= 1)
// {
// // i从k开始每次+1,a[i]与a[i-k]比较
// for (int i = k; i < len; i++)
// {
// for (int j = i; j >= k && (a[j] < a[j - k]); j -= k)
// {
// T temp = a[j];
// a[j] = a[j - k];
// a[j - k] = temp;
// }
// }
// // 计算下一轮步长
// k = k / 2;
// }
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
int s[] = {50, -1, 3, 4, 0, 5, 1000, 6, 7, 12, 8, 1, 2, 9, -530, 450, 77} ;
int len = sizeof(s)/sizeof(s[0]);
ShellSort(s, len);
mDebug(s, len);
return a.exec();
}
输出
"-530 -1 0 1 2 3 4 5 6 7 8 9 12 50 77 450 1000 "