薄荷丶微微凉

人生若只如初见,何事秋风悲画扇。

希尔排序算法

import cn.idestiny.util.GeneratedArray;

/**
 * @Auther: FAN
 * @Date: 2018/8/25 22:25
 * @Description:希尔排序
 *
 * 重点:设置增量
 *   举例来说,含有1000个数据项的数组可能先以364为增量,然后以121为增量,以40为增量,
 *   以13为增量,以4为增量,最后以 1为增量进行希尔排序。用来形成间隔的数列被称为间隔序列。
 *   这里所表示的间隔序列由Knuth提出,此序列是很常用的。
 *   数列以逆向形式从1开始,通过递归表达式 h=3*b+1 来产生,初始值为1。
 *
 * 当增量为arr.length/2的时候
 * 1) 8,5,7,1,3,6,9.4  [8,3],[5,6]  [7,9],[1,4]
 * 2) 3,5,7,1,8,6,9,4  [3,7,8,9]  [5,1,6,4]
 * 3) 3,1,7,4,8,5,9,6  [3,1,7,4,8,5,9,6]
 * 4) 1,3,4,5,6,7,8,9
 **/
public class ShellSort {

    public static void main(String[] args) {

        int[] arr = GeneratedArray.randomGeneratedArray(10, 50, 100000);
        long start = System.currentTimeMillis();
        shellSort(arr);
        GeneratedArray.isSorted(arr);
        System.out.println(System.currentTimeMillis()-start);
    }

    public static void shellSort(int[] arr) {

        //数组长度
        int size = arr.length;
        //设置间隔序列 详细请看文档注释
        int h = 1;
        while(h<size/3){
            h = 3*h +1;
        }
        //根据增量分组,增量为1时,只需要插入排序算法微调即可
        while(h>=1){
            //对每个分组执行插入排序算法
            for(int i = h;i<size;i++){
                //记录插入值
                int key = arr[i];
                //插入值前一个元素的位置
                int j = i-h;
                //如果插入之比前一个值大,则插入之只需向后排列即可,不用在和前面的元素比较。
                while(j>=0&&arr[j]>key){
                    //如果插入值比它前面的值小,则大值(插入值前面的值)向后移动一位,
                    arr[j+h] = arr[j];
                    //插入值之前的角标
                    j -= h;
                }
                //插入值最终应该放置的位置
                arr[j+h] = key;

            }
            //缩小增量
            h /= 3;
        }

    }

}

 

posted @ 2018-08-26 12:13  淡淡薄荷丶微微凉  阅读(105)  评论(0编辑  收藏  举报