希尔排序是要分组插入排序,而后,统一起来进行排序。
所以,那个决定分组的间距要不断缩短。
在代码中,d即为间距。
#include <iostream>
using namespace std;
void SellSort(int a[], int M)
{
int i,j,d;
int tmp;
for(d = M/2 ; d >= 1; d /= 2) //对记录分组排序
{
for( i = d; i <= M; i++) //对每一组记录排序
{
tmp = a[i];
for(j = i - d; j >= 0 && tmp < a[j]; j -= d)
a[j+d] = a[j];
a[j+d] = tmp;
}
}
for(int ii = 0; ii < M; ii++)
cout << a[ii] << endl;
}
void main()
{
cout << "请输入十个数" << endl;
int ForSort[10];
for (int ii = 0; ii < 10; ii++)
{
cin >> ForSort[ii];
}
printf("\n");
SellSort(ForSort,10); //初始增量设为5
}
上述代码实在简洁漂亮,但我只想说一句,滚你妈个鬼哦,我根本看不懂!
下面我用其他的代码来分析。
首先要知道希尔排序的基础是直接插入排序。
先记下直接插入排序的代码。
void InsertSort(SqList &L)
{
for(i = 2; i <= L.length; ++i){
if(LT(L.r[i].key, L.r[i - 1].key)){
L.r[0] = L.r[i];
L.r[i] = L.r[i - 1];
for(j = i - 1; LT(L.r[0].key,L.r[j].key); --j)
L.r[j + 1] = L.r[j];
L.r[j + 1] = L.r[0];
}
}
}
然后是,希尔排序
void ShellInsert(SqList &L, int dk){
for(i = dk + 1; i <= L.length; ++i){
if(LT(L.r[i].key,L.r[i-dk].key)){
L.r[0] = L.r[i];
for(J = i-dk; j>0&<(L.r[0].key,L.r[j].key); j-=dk)
L.r[j+dk] = L.r[j];
L.r[j+dk] = L.r[0];
}
}
}
void ShellSort(SqList &L, int dlta[], int t){
for(k = 0; k < t; ++k)
ShellInsert(L, dlta[k]);
}
有上述代码可知,除了增量由1变为dk外,希尔排序与直接插入排序的代码差别不大!
可上述代码仍然只是没法运行的伪代码,让我来亲自实现它!
2014.1.6 作为练习随便写的,是那个意思吧。。。
#include <iostream>
using namespace std;
class Shell
{
public:
void ShellInsert(int a[], int M);
void ShellSort(int x[],int M);
};
void Shell::ShellSort(int a[], int M)
{
for(int i = M; i >= 1; i/=2) // 增量的减少
{
ShellInsert(a, i);
}
for(int j = 1; j < 11; j++ )
cout << a[j] << endl;
}
void Shell::ShellInsert(int x[], int M)
{
int j;
for(int i = 2; i <= 10; i+= M)
{
if(x[i] < x[i-M])
{
x[0] = x[i];
x[i] = x[i - M];
for(j = i - 2*M; x[0] < x[j]; j-=M)
{
x[j+M] = x[j];
}
x[j+M] = x[0];
}
}
}
int main()
{
Shell myShell;
int i;
int num[11];
cout << "请输入10个数字" << endl;
for(i = 1;i < 11; i++ )
cin >> num[i];
myShell.ShellSort(num,5); // 增量设为5
}