希尔排序的具体分析见http://blog.csdn.net/morewindows/article/details/6668714/
/************************
author's email:wardseptember@gmail.com
date:2017.12.11
希尔排序
************************/
#include<iostream>
#define maxSize 10
using namespace std;
void shellSort1(int *a, int n);
void shellSort2(int *a, int n);
void Swap(int &a, int &b);//交换函数
void shellSort3(int *a, int n);
void printArray(int D[], int n);
void main() {
int D[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };//构造一个一维数组
int E[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };
int F[maxSize] = { 12,15,48,46,16,78,57,88,65,48 };
shellSort1(D, maxSize);
cout << "希尔排序第一种算法结果为:" << endl;
printArray(D, maxSize);
shellSort2(E, maxSize);
cout << "希尔排序第二种算法结果为:" << endl;
printArray(E, maxSize);
shellSort3(F, maxSize);
cout << "希尔排序第三种算法结果为:" << endl;
printArray(F, maxSize);
}
void shellSort1(int *a, int n) {
int i, j;
int inc;//代表增量
for(inc=n/2;inc>0;inc/=2)//希尔排序的增量选择都是从n/2开始,每次再减半,直到最后为1
for (i = 0; i < inc; ++i) {//直接插入排序的应用,每一组组内进行排序,可与直接插入排序算法对比理解
for(j=i+inc;j<n;j+=inc)//每次增加inc。用于找到这些元素
if (a[j] < a[j - inc]) {/*在循环刚开始时加上一句判断,若a[j]>=a[i-inc]说明a[0...j]本身就是有序的,无需调整,否则按就调整。*/
int temp = a[j];
int k = j - inc;
while (k >= 0 && a[k] > temp) {//找到要插入的位置,并将a[k+inc]前面的数后移
a[k + inc] = a[k];
k -= inc;
}
a[k + inc] = temp;//因为最后k减一个temp,所以这里加一个
}
}
}
/*对比第一种方法可以发现,第二种方法少了一层循环,可以理解为把两个循环合并为一个循环
,两种方法都是每组组内进行直接插入排序,遍历完所有元素即可。显而易见,从时间复杂度上来看,第二种方法更简单
*/
void shellSort2(int *a, int n)
{
int j, inc;//inc代表增量
for (inc = n / 2; inc > 0; inc /= 2)
for (j = inc; j < n; j++)//从数组第gap个元素开始
if (a[j] < a[j - inc])//每个元素与自己组内的数据进行直接插入排序
{
int temp = a[j];
int k = j - inc;
while (k >= 0 && a[k] > temp)
{
a[k + inc] = a[k];
k -= inc;
}
a[k + inc] = temp;
}
}
void Swap(int &a, int &b) //引用类型方式
{
int temp; //辅助变量
temp = a;
a = b;
b = temp;
}
/*
第三种方法是用元素交换的方法代替数组后移
*/
void shellSort3(int *a, int n)
{
int i, j, inc;
for (inc = n / 2; inc > 0; inc /= 2)
for (i = inc; i < n; i++)
for (j = i - inc; j >= 0 && a[j] > a[j + inc]; j -= inc)//将前面两种方法的几句代码,合并为一句。对比理解
Swap(a[j], a[j + inc]);
}
void printArray(int D[], int n) {
for (int i = 0; i < n; ++i) //输出排序后的关键字
cout << D[i] << " ";
cout << endl;
}