作为初学者,看到书中希尔算法部分,完全不知道书上的内容是写的什么,一个个N,K,J等符号,看的我如坠入云中,不知所云。书上的推导过程更加让我迷惑,根本不知道数与数之间是如何产生关系的。
于是我上网搜索关于希尔排序的文章,大部分文章写几句关键点并把实现代码写出来就没有了,而且语言晦涩难懂,本来就不理解什么是希尔排序,看到这样的文章更加迷惑。
翻看的多篇文章之后,终于找到了一篇适合我看的文章-
作者通过一个数组例子,详细的分析了希尔排序代码的执行过程,并给出了不同简化程度的源代码。说了这么多,好像是做广告了。呵呵,反正我是看这篇文章,学会了希尔排序。package it.cast.sort;
public class Shellsort {// 希尔算法(shell)核心思想:
/*
* 将一组比较长多的数按照一定的 数学公式进行分组(有很多分组方法,没有定论,这里选用gap=gap/2的分组方法,但是最后一个gap必须等于1)
* 分组结束后,在组内进行插入算法排序。每进行一次分组,就进行一次插入排序。当gap=1进行分组并排序完成后 shell算法整体结束
*/
// 建议按照代码手动推导几个循环,观察推导过程,这样做便于理解代码的含义。
// 最容易理解,最直观的希尔排序
public static void shellsort1(int[] a) {
for (int gap = a.length / 2; gap > 0; gap /= 2) {
for (int i = 0; i < gap; i++) {
for (int j = gap+i; j < a.length; j += gap) {
if (a[j] < a[j -gap]){
int temp = a[j]; int k = j - gap;
for (; k >= 0 &&a[k] > temp; k -= gap) {
a[k + gap] = a[k]; }
a[k + gap] = temp; } }// 插入算法
}
}
}
// 经过简化的shell算法
public static void shellsort2(int[] a) {
for (int gap = a.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < a.length; i++) {
if (a[i] < a[i - gap]) {
int temp = a[i];
int k = i - gap;
for (; k >= 0 && a[k] > temp; k -= gap) {
a[k + gap] = a[k];
}
a[k + gap] = temp;
}
}
}
}
// 更加简介的算法(将直接插入算法改为了冒泡算法)
public static void shellsort3(int[] a) {
for (int gap = a.length / 2; gap > 0; gap /= 2) {
for (int i = gap; i < a.length; i++) {
for (int k = i - gap; k >= 0 && a[k] > a[k + gap]; k -= gap)
/*
* 将插入算法改为了冒泡算法 , 即相邻之间的数据进行比较 , 如果前面的数据大于后边的数据 , 然后进行位置交换
*/
{
int t = a[k + gap];
a[k + gap] = a[k];
a[k] = t;
}
}
}
}
//测试
public static void main(String[] arge) {
int a[] = { 1, 4, 3, 2, 6, 5, 43, 6, 6, 8, 90, 5, 64, 4, 65, 445, 3,
4343, 3432211, 12, 211, 12 };
// 统计所用时间
double begin = System.currentTimeMillis(); // 这段代码放在程序执行前
for (int i = 0; i < 100000; i++) {
// shellsort(a);
// shellsort(a);
shellsort1(a);
// shellsort2(a);
// shellsort3(a);
}
double end = System.currentTimeMillis() - begin; // 这段代码放在程序执行后
System.out.println("耗时:" + end + "毫秒");
//遍历数组中的数字
for (int i = 0; i < a.length; i++) {
System.out.println(a[i]);
}
}
}