每日一題(算法:希爾排序 及其優化)

希爾排序思路
標題

希爾排序算法圖解

 

package com.athangzhou.springcloud.service.impl;

import com.alibaba.fastjson.JSON;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 希爾排序   8萬條數據,希爾算法
 * 位移法 用時1秒 性能高
 * 交換法 用時6秒 性能低
 */
public class ShellSort {


    public static void main(String[] args) {
        int arr[] = {0, 9, 2, 4, 5, 6, 8, 1, 3, 7};

        int[] testArr = new int[80000];
        for (int i = 1; i < 80000; i++) {
            testArr[i] = (int) (Math.random() * 80000);
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = simpleDateFormat.format(new Date());
        System.out.println("希爾算法:移位法計算開始時間" + format);

        shellSort(testArr);

        String formatEnd = simpleDateFormat.format(new Date());
        System.out.println("希爾算法:位移法 計算結束時間" + formatEnd);

        System.out.println("");
        System.out.println("");
        System.out.println("");
        System.out.println("");

        String exchangeSortStart = simpleDateFormat.format(new Date());
        System.out.println("希爾算法:交換法計算開始時間" + exchangeSortStart);
        exchangeSort(testArr);
        String exchangeSortEnd = simpleDateFormat.format(new Date());
        System.out.println("希爾算法:交換法計算結束時間" + exchangeSortEnd);

    }

    //希爾排序算法 移位法
    public static void shellSort(int[] arr) {
        int count = 0;
        //分組思想
        for (int group = arr.length / 2; group > 0; group /= 2) {
            //第二步 分爲2組  即5/2=2  {0,1,5,9,4},{8,3,6,2,7} 最後結果:{0,2,1,3,4,6,5,7,9,8}
            //從第group個元素依次對其所在的組進行直接插入排序
            for (int i = group; i < arr.length; i++) {
                //要插入數的索引  0
                int j = i;
                //要插入數的值  arr[5]=6
                //{0,9,2,4,5,6,8,1,3,7}
                //{0,6},{9,8},{2,1},{4,3},{5,7}
                //{0,9,2,4,5,6,8,1,3,7}
                int insertValue = arr[j];
                //比較 arr[5]與arr[0]的值  如果小於 則移位插入
                //步長
                if (arr[j] < arr[j - group]) {
                    while (j - group >= 0 && insertValue < arr[j - group]) {
                        arr[j] = arr[j - group];
                        j -= group;
                    }
                }
                //退出while循環說明temp找到了位置
                arr[j] = insertValue;
            }
            //   System.out.println("第" + (++count) + "次插入結果: " + JSON.toJSONString(arr));
        }
        //  System.out.println("JSON.toJSONString(arr) = " + JSON.toJSONString(arr));
    }

    /**
     * 希爾排序交換算法  從小到大排序
     * <p>
     * 如果從大到小排序,>改爲<即可
     *
     * @param arr arr
     */
    public static void exchangeSort(int arr[]) {
        int temp = 0;
        int count = 0;
        for (int group = arr.length / 2; group > 0; group /= 2) {
            //因爲第一次分爲了5組,所以從索引下標=5開始
            for (int i = group; i < arr.length; i++) {
                //只遍歷兩次  從0開始
                for (int j = i - group; j >= 0; j -= group) {
                    if (arr[j] > arr[j + group]) {
                        temp = arr[j];
                        arr[j] = arr[j + group];
                        arr[j + group] = temp;
                    }
                }
            }
            //    System.out.println("第" + (++count) + "次排序結果:" + JSON.toJSONString(arr));
        }
      /*  int groupTest = arr.length / 2;
        while (groupTest > 0) {
            //因爲第一次分爲了5組,所以從索引下標=5開始
            for (int i = groupTest; i < arr.length; i++) {
                //只遍歷兩次  從0開始
                for (int j = i - groupTest; j >= 0; j -= groupTest) {
                    if (arr[j] > arr[j + groupTest]) {
                        temp = arr[j];
                        arr[j] = arr[j + groupTest];
                        arr[j + groupTest] = temp;
                    }
                }
            }
            System.out.println("第" + groupTest + "次排序結果:" + JSON.toJSONString(arr));
            groupTest = groupTest / 2;
        }*/
    }

    /**
     * 希爾排序思路:
     * {0,9,2,4,5,6,8,1,3,7}
     * <p>
     * 第一步: 分爲5組 即length/2  10/2=5  {0,6},{9,8},{2,1},{4,3},{5,7}  各自比較大小 小數放前面,大數放後面替換位置
     * 最後結果: {0,8,1,3,5,6,9,2,4,7}
     * <p>
     * 第二步 分爲2組  即5/2=2  {0,1,5,9,4},{8,3,6,2,7}
     * 最後結果:{0,2,1,3,4,6,5,7,9,8}
     * <p>
     * 第三步: 分爲1組  即2/2    {0,2,1,3,4,6,5,7,9,8}
     * 最後結果:{0,1,2,3,4,5,6,7,8,9}
     */
    public static void test(int arr[]) {


        int temp = 0;
        //因爲第一次分爲了5組,所以從索引下標=5開始
        for (int i = 5; i < arr.length; i++) {
            //只遍歷兩次  從0開始
            for (int j = i - 5; j >= 0; j -= 5) {
                if (arr[j] < arr[j + 5]) {
                    temp = arr[j];
                    arr[j] = arr[j + 5];
                    arr[j + 5] = temp;
                }
            }
        }
        System.out.println("第一次排序結果:" + JSON.toJSONString(arr));

        //因爲第二次分爲了5/2=2組,所以從索引下標=2開始  [0,8,1,3,5,6,9,2,4,7]
        //第二步 分爲2組  即5/2=2  {0,1,5,9,4},{8,3,6,2,7}
        // 最後結果:{0,2,1,3,4,6,5,7,9,8}
        for (int i = 2; i < arr.length; i++) {
            //只遍歷兩次  從0開始
            for (int j = i - 2; j >= 0; j -= 2) {
                if (arr[j + 2] < arr[j]) {
                    temp = arr[j];
                    arr[j] = arr[j + 2];
                    arr[j + 2] = temp;
                }
            }
        }
        System.out.println("第二次排序結果:" + JSON.toJSONString(arr));


        //因爲第二次分爲了5/2=2組,所以從索引下標=2開始  [0,8,1,3,5,6,9,2,4,7]
        //第二步 分爲2組  即5/2=2  {0,1,5,9,4},{8,3,6,2,7}
        // 最後結果:{0,2,1,3,4,6,5,7,9,8}
        for (int i = 1; i < arr.length; i++) {
            //只遍歷兩次  從0開始
            for (int j = i - 1; j >= 0; j -= 1) {
                if (arr[j + 1] < arr[j]) {
                    temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        System.out.println("第三次排序結果:" + JSON.toJSONString(arr));
    }


}

打印結果:

希爾算法:移位法計算開始時間2020-04-22 23:56:24
希爾算法:位移法 計算結束時間2020-04-22 23:56:24


希爾算法:交換法計算開始時間2020-04-22 23:56:24
希爾算法:交換法計算結束時間2020-04-22 23:56:30

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章