希尔(Shell sort)算法

       作为初学者,看到书中希尔算法部分,完全不知道书上的内容是写的什么,一个个N,K,J等符号,看的我如坠入云中,不知所云。书上的推导过程更加让我迷惑,根本不知道数与数之间是如何产生关系的。

       于是我上网搜索关于希尔排序的文章,大部分文章写几句关键点并把实现代码写出来就没有了,而且语言晦涩难懂,本来就不理解什么是希尔排序,看到这样的文章更加迷惑。

      翻看的多篇文章之后,终于找到了一篇适合我看的文章-

白话经典算法系列之三 希尔排序的实现(http://blog.csdn.net/morewindows/article/details/6668714)

作者通过一个数组例子,详细的分析了希尔排序代码的执行过程,并给出了不同简化程度的源代码。说了这么多,好像是做广告了。呵呵,反正我是看这篇文章,学会了希尔排序。

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]);
        }
    }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值