常见的七种排序算法性能比较测试

常见的七种排序算法性能比较测试

目录

排序算法分析

算法名称时间复杂度(平均)时间复杂度(最坏)时间复杂度(最好)空间复杂度稳定性
选择排序O( n2 n 2 )O( n2 n 2 )O( n2 n 2 )O(1)不稳定
堆排序O( nlog2n n log 2 ⁡ n )O( nlog2n n log 2 ⁡ n )O( nlog2n n log 2 ⁡ n )O(1)不稳定
插入排序O( n2 n 2 )O( n2 n 2 )O(n)O(1)稳定
希尔排序O( n1.3 n 1.3 )O( n2 n 2 )O(n)O(1)不稳定
冒泡排序O( n2 n 2 )O( n2 n 2 )O(n)O(1)稳定
快速排序O( nlog2n n log 2 ⁡ n )O( n2 n 2 )O( nlog2n n log 2 ⁡ n )O( log2n log 2 ⁡ n )不稳定
归并排序O( nlog2n n log 2 ⁡ n )O( nlog2n n log 2 ⁡ n )O( nlog2n n log 2 ⁡ n )O(n)稳定

测试报告

进行两组测试,最终结果还是没有JDK中自带的Arrays.sort() 排序函数优化,在一千万以内的数据量时,基本上都有可以保证在1秒以内完成排序,在一亿的数据量时,基本上在10秒左右就可以完成排序。
随着数据量的急剧增加,在我实现的排序算法中,快速排序的是最快的,堆排序是最慢的。
结论:快速排序 > 归并排序 > 希尔排序 > 堆排序
第一组测试由一百万到一千万
这里写图片描述
第二组测试由一千万到一亿
这里写图片描述
2018-04-16 增加
第三组测试 一亿到五亿(需要配置一下jvm参数,不然会导致堆内存溢出 )
这里写图片描述
配置jvm参数 -Xmx6144M -Xms6144M
这里写图片描述

代码地址

github:https://github.com/chengchuanqiang/algorithm

代码

package algorithm.sort;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;

public class TestSort {

    public static void main(String[] args) {
        Map<String, Map<Integer, Long>> map = new LinkedHashMap<String, Map<Integer,Long>>();
        init(map);
        int i = 10_000_000;
        int n = 100_000_000;
        int step = 10_000_000;
        long s = 0;
        long e = 0;
        int num = 1;
        for (; i <= n; i = i + step) {
            int[] source = new int[i];
            int[] result = new int[i];
            for (int j = 0; j < i; j++) {
                source[j] = new Random().nextInt() % i;
            }
            //print(source);

            System.out.println("---------------------------第  "+ num++ +" 次,数据量:" + i + "----------------------------");

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            insertSort(result);
            e = System.currentTimeMillis();
            System.out.println("插入排序时间:" + (e - s));
            map.get("insertSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            bubbleSort(result);
            e = System.currentTimeMillis();
            System.out.println("冒泡排序时间:" + (e - s));
            map.get("bubbleSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            selectSort(result);
            e = System.currentTimeMillis();
            System.out.println("选择排序时间:" + (e - s));
            map.get("selectSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            Arrays.sort(result);
            e = System.currentTimeMillis();
            System.out.println("JDK Arrays.sort 排序时间:" + (e - s));
            map.get("ArraysSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            result = mergeSort(result);
            e = System.currentTimeMillis();
            System.out.println("归并排序1时间:" + (e - s));
            map.get("mergeSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            mergeSort2(result, 0, result.length - 1);
            e = System.currentTimeMillis();
            System.out.println("归并排序2时间:" + (e - s));
            map.get("mergeSort2").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            quickSort(result, 0, result.length - 1);
            e = System.currentTimeMillis();
            System.out.println("快速排序1时间:" + (e - s));
            map.get("quickSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            quickSort2(result, 0, result.length - 1);
            e = System.currentTimeMillis();
            System.out.println("快速排序2时间:" + (e - s));
            map.get("quickSort2").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            quickSort3(result, 0, result.length - 1);
            e = System.currentTimeMillis();
            System.out.println("快速排序3时间:" + (e - s));
            map.get("quickSort3").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            heapSort(result);
            e = System.currentTimeMillis();
            System.out.println("堆排序时间:" + (e - s));
            map.get("heapSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            shellSort(result);
            e = System.currentTimeMillis();
            System.out.println("希尔排序1时间:" + (e - s));
            map.get("shellSort").put(i, (e - s));
            //print(result);

            System.arraycopy(source, 0, result, 0, source.length);
            s = System.currentTimeMillis();
            shellSort2(result);
            e = System.currentTimeMillis();
            System.out.println("希尔排序2时间:" + (e - s));
            map.get("shellSort2").put(i, (e - s));
            //print(result);
        }

        printResult(map);

    }

    /***          
     *** @illustration: 初始化              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:22:57
     *** @version     : v1.0.x                  
     ***/
    public static void init(Map<String, Map<Integer, Long>> map){
        Map<Integer, Long> timeMap1 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap2 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap3 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap4 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap5 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap6 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap7 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap8 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap9 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap10 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap11 = new LinkedHashMap<Integer, Long>();
        Map<Integer, Long> timeMap12 = new LinkedHashMap<Integer, Long>();
        map.put("insertSort", timeMap1);
        map.put("bubbleSort", timeMap2);
        map.put("selectSort", timeMap3);
        map.put("ArraysSort", timeMap4);
        map.put("mergeSort", timeMap5);
        map.put("mergeSort2", timeMap6);
        map.put("quickSort", timeMap7);
        map.put("quickSort2", timeMap8);
        map.put("quickSort3", timeMap9);
        map.put("heapSort", timeMap10);
        map.put("shellSort", timeMap11);
        map.put("shellSort2", timeMap12);
    }

    /***          
     *** @illustration: 打印输出时间              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:22:57
     *** @version     : v1.0.x                  
     ***/
    public static void printResult(Map<String, Map<Integer, Long>> map){

        for(Entry<String, Map<Integer, Long>> entry : map.entrySet()){
            Map<Integer, Long> value = entry.getValue();
            System.out.print("\t\t");
            for(Entry<Integer, Long> time : value.entrySet()){
                Integer num = time.getKey();
                System.out.print(num + "\t");
            }
            System.out.println();
            System.out.println();
            break;
        }
        for(Entry<String, Map<Integer, Long>> entry : map.entrySet()){
            String key = entry.getKey();
            Map<Integer, Long> value = entry.getValue();
            System.out.print(key + "\t");
            for(Entry<Integer, Long> time : value.entrySet()){
                Long timeVal = time.getValue();
                System.out.print(timeVal + "ms\t");
            }
            System.out.println();
        }
    }

    /***          
     *** @illustration: 输出数组内容              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:22:57
     *** @version     : v1.0.x                  
     ***/
    public static void print(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + " ");
        }
        System.out.println();
    }


    /***          
     *** @illustration: 交换数组arr中i、j位置的值               
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:23:35
     *** @version     : v1.0.x                  
     ***/
    public static void swap(int[] arr, int i, int j) {
        if (i != j) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    /***          
     *** @illustration: 选择排序              
     *** @Description : 时间复杂度(平均):O(n^2)         时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(n^2)     空间复杂度:O(1) 稳定性:不稳定 
     ***                每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放在序列的起始位置,直到全部待排序的数据元素排完                 
     *** @author      : 程传强                   
     *** @date        : 2018-4-12下午3:02:28
     *** @version     : v1.0.x                  
     ***/
    public static void selectSort(int[] a) {
        int len = a.length;
        for (int i = 0; i < len - 1; i++) {
            int min = i;
            for (int j = i + 1; j < len; j++) {
                if (a[j] < a[min]) {
                    min = j;
                }
            }
            swap(a, min, i);
        }
    }

    /***          
     *** @illustration: 归并排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(nlogn)   时间复杂度(最好):O(nlogn)     空间复杂度:O(n) 稳定性:稳定 
     ***                该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
     ***                将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。                 
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:25:02
     *** @version     : v1.0.x                  
     ***/
    public static int[] mergeSort(int[] a) {

        if (a.length == 1) {
            return a;
        }
        int[] aLeft = new int[a.length / 2];
        int[] aRight = new int[a.length % 2 == 1 ? (a.length / 2 + 1) : a.length / 2];
        for (int i = 0; i < aLeft.length; i++) {
            aLeft[i] = a[i];
        }
        for (int i = 0; i < aRight.length; i++) {
            aRight[i] = a[a.length - aRight.length + i];
        }
        int[] aLeftRes = mergeSort(aLeft);
        int[] aRigthRes = mergeSort(aRight);
        int[] res = merge(aLeftRes, aRigthRes);
        return res;
    }

    /***          
     *** @illustration: 将两个有序的数组合成一个有序的数组             
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:26:25
     *** @version     : v1.0.x                  
     ***/
    private static int[] merge(int[] aLeftRes, int[] aRigthRes) {
        int[] a = new int[aLeftRes.length + aRigthRes.length];
        int llen = aLeftRes.length;
        int rlen = aRigthRes.length;
        int index = 0;
        int lindex = 0;
        int rindex = 0;
        while (lindex < llen && rindex < rlen) {
            if (aLeftRes[lindex] < aRigthRes[rindex]) {
                a[index++] = aLeftRes[lindex++];
            } else if (aLeftRes[lindex] == aRigthRes[rindex]) {
                a[index++] = aLeftRes[lindex++];
                a[index++] = aRigthRes[rindex++];
            } else if (aLeftRes[lindex] > aRigthRes[rindex]) {
                a[index++] = aRigthRes[rindex++];
            }
        }
        while (lindex < llen) {
            a[index++] = aLeftRes[lindex++];
        }
        while (rindex < rlen) {
            a[index++] = aRigthRes[rindex++];
        }
        return a;
    }

    /***          
     *** @illustration: 归并排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(nlogn)   时间复杂度(最好):O(nlogn)     空间复杂度:O(n) 稳定性:稳定 
     ***                该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
     ***                将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。                 
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:25:02
     *** @version     : v1.0.x                  
     ***/
    public static int[] mergeSort2(int[] arr, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            mergeSort2(arr, low, mid);
            mergeSort2(arr, mid + 1, high);
            merge2(arr, low, mid, high);
        }
        return arr;
    }

    /***          
     *** @illustration: 将有序数组arr[low...mid] 与  arr[mid+1...high]合成一个有序数组 arr[low...high]              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:30:38
     *** @version     : v1.0.x                  
     ***/
    public static void merge2(int[] arr, int low, int mid, int high) {
        int[] a = new int[high - low + 1];
        int index = 0;
        int lindex = low;
        int rindex = mid + 1;
        while (lindex <= mid && rindex <= high) {
            if (arr[lindex] < arr[rindex]) {
                a[index++] = arr[lindex++];
            } else if (arr[lindex] == arr[rindex]) {
                a[index++] = arr[lindex++];
                a[index++] = arr[rindex++];
            } else if (arr[lindex] > arr[rindex]) {
                a[index++] = arr[rindex++];
            }
        }
        while (lindex <= mid) {
            a[index++] = arr[lindex++];
        }
        while (rindex <= high) {
            a[index++] = arr[rindex++];
        }
        for (int i = 0; i < a.length; i++) {
            arr[i + low] = a[i];
        }
    }

    /***          
     *** @illustration: 分隔函数,将大于轴的数全部交换到轴的右边,小于轴的数全部交换到轴的左边,并返回轴的位置(每次以high位置为轴)              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:32:22
     *** @version     : v1.0.x                  
     ***/
    public static int partition(int[] arr, int low, int high) {
        int base = arr[high];
        while (low < high) {
            while (low < high && arr[low] <= base) {
                low++;
            }
            if (low < high) {
                swap(arr, low, high);
                high--;
            }
            while (low < high && arr[high] >= base) {
                high--;
            }
            if (low < high) {
                swap(arr, low, high);
                low++;
            }
        }
        // print(arr);
        return high;
    }

    /***          
     *** @illustration: 快速排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(nlogn)   空间复杂度:O(nlogn) 稳定性:不稳定
     ***                通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
     ***                然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:55:03
     *** @version     : v1.0.x                  
     ***/
    public static void quickSort(int arr[], int low, int high) {
        if (low >= high)
            return;
        int partition = partition(arr, low, high);
        quickSort(arr, low, partition - 1);
        quickSort(arr, partition + 1, high);
    }

    /***          
     *** @illustration: 分隔函数,将大于轴的数全部交换到轴的右边,小于轴的数全部交换到轴的左边,并返回轴的位置(每次以high位置为轴)              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:32:22
     *** @version     : v1.0.x                  
     ***/
    public static int partition2(int[] arr, int low, int high) {
        int base = arr[low];
        while (low < high) {
            while (low < high && arr[high] >= base) {
                high--;
            }
            if (low < high) {
                swap(arr, low, high);
                low++;
            }
            while (low < high && arr[low] <= base) {
                low++;
            }
            if (low < high) {
                swap(arr, low, high);
                high--;
            }
        }
        // print(arr);
        return high;
    }

    /***          
     *** @illustration: 快速排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(nlogn)   空间复杂度:O(nlogn) 稳定性:不稳定
     ***                通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
     ***                然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:55:03
     *** @version     : v1.0.x                  
     ***/
    public static void quickSort2(int arr[], int low, int high) {
        if (low >= high)
            return;
        int partition = partition2(arr, low, high);
        quickSort2(arr, low, partition - 1);
        quickSort2(arr, partition + 1, high);
    }

    /***          
     *** @illustration: 快速排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(nlogn)   空间复杂度:O(nlogn) 稳定性:不稳定
     ***                通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,
     ***                然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:55:03
     *** @version     : v1.0.x                  
     ***/
    public static void quickSort3(int arr[], int low, int high) {
        if (low > high) {
            return;
        }
        int base = arr[low];
        int i = low;
        int j = high;
        while (i < j) {
            while (arr[j] >= base && i < j)
                j--;
            while (arr[i] <= base && i < j)
                i++;
            if (i < j)
                swap(arr, i, j);
        }
        arr[low] = arr[i];
        arr[i] = base;
        quickSort3(arr, low, i - 1);
        quickSort3(arr, i + 1, high);
    }

    /***          
     *** @illustration: 堆调整,将a数组中的 第 i 个元素进行堆调整(大顶堆)              
     *** @Description : Description                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:34:05
     *** @version     : v1.0.x                  
     ***/
    public static void heapAdjust(int[] a, int len, int i) {
        int max = i;
        int curr = i;
        while (max < len) {
            int lchild = (curr << 1) + 1;
            int rchild = (curr << 1) + 2;
            // System.out.println(curr + " " + lchild +" " + rchild);
            if (lchild < len && a[max] < a[lchild]) {
                max = lchild;
            }
            if (rchild < len && a[max] < a[rchild]) {
                max = rchild;
            }
            if (curr == max) {
                break;
            }
            swap(a, max, curr);
            curr = max;
        }
    }

    /***          
     *** @illustration: 堆排序              
     *** @Description : 时间复杂度(平均):O(nlogn)       时间复杂度(最坏):O(nlogn)   时间复杂度(最好):O(nlogn)     空间复杂度:O(1) 稳定性:不稳定 
     ***                初始时把要排序的数的序列看作是一棵顺序存储的二叉树,调整它们的存储序,使之成为一个堆,这时堆的根节点的数最大。
     ***                然后将根节点与堆的最后一个节点交换,对前面(n-1)个数重新调整使之成为堆;
     ***                依此类推,直到只有两个节点的堆,并对它们作交换,最后得到有n个节点的有序序列。
     ***                从算法描述来看,堆排序需要两个过程,一是建立堆,二是堆顶与堆的最后一个元素交换位置。
     ***                所以堆排序有两个函数组成。一是建堆的调整函数,二是反复调用调整函数实现排序的函数。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:35:24
     *** @version     : v1.0.x                  
     ***/
    public static void heapSort(int[] a) {
        int len = a.length;
        // 将数组a转化为大顶堆
        for (int i = len / 2; i >= 0; i--) {
            heapAdjust(a, len, i);
        }
        swap(a, 0, len - 1);
        for (int i = 1; i < len; i++) {
            heapAdjust(a, len - i, 0);
            swap(a, 0, len - i - 1);
        }
    }

    /***          
     *** @illustration: 冒泡排序              
     *** @Description : 时间复杂度(平均):O(n^2)         时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(n)   空间复杂度:O(1) 稳定性:稳定
     ***                冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。
     ***                走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:18:17
     *** @version     : v1.0.x                  
     ***/
    public static void bubbleSort(int[] a) {
        int len = a.length;
        for (int i = 0; i < len - 1; i++) {
            boolean flag = true;
            for (int j = 0; j < len - 1 - i; j++) {
                if (a[j] > a[j + 1]) {
                    swap(a, j, j + 1);
                    flag = false;
                }
            }
            if(flag){
                break;
            }
        }
    }

    /***          
     *** @illustration: 插入排序              
     *** @Description : 时间复杂度(平均):O(n^2)         时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(n)   空间复杂度:O(1) 稳定性:稳定  
     ***                每步将一个待排序的记录,按其关键码值的大小插入前面已经排序的文件中适当位置上,直到全部插入完为止。                  
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:15:19
     *** @version     : v1.0.x                  
     ***/
    public static void insertSort(int[] a) {
        for (int i = 1; i < a.length; i++) {
            int j = i;
            int temp = a[i];
            while(j > 0 && a[j - 1] > temp){
                a[j] =a[j-1]; 
                j--;
            }
            a[j] = temp;
        }
    }

    /***          
     *** @illustration: 希尔排序            
     *** @Description : 分组插入方法,步长逐渐减半,直到为1  (n/2 n/4 n/8 ... n/(2^n) ... 1) 
     ***                时间复杂度(平均):O(n^1.3)  时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(n)   空间复杂度:O(1)  稳定性:不稳定 
     ***                希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
     ***                随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止 。            
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午9:11:40
     *** @version     : v1.0.x                  
     ***/
    public static void shellSort(int[] a){
        int len = a.length;
        for(int i = len / 2; i > 0; i = i/2){
            for(int j = i; j < len; j++){
                int temp = a[j];
                int index = j;
                while(index - i >= 0 && a[index - i] > temp){
                    a[index] = a[index - i];
                    index = index - i;
                }
                a[index] = temp;
            }
        }
    }

    /***          
     *** @illustration: 希尔排序              
     *** @Description : 分组插入方法,步长逐渐缩小3倍,直到1  (1,4,13,40,121 ...)
     ***                时间复杂度(平均):O(n^1.3)  时间复杂度(最坏):O(n^2)   时间复杂度(最好):O(n)   空间复杂度:O(1)  稳定性:不稳定 
     ***                希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;
     ***                随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止。                 
     *** @author      : 程传强                   
     *** @date        : 2018-4-12上午10:00:50
     *** @version     : v1.0.x                  
     ***/
    public static void shellSort2(int[] a) {
        int len = a.length;
        int h = 1;
        while (h < len / 3) {
            h = h * 3 + 1;
        }
        while (h >= 1) {
            for (int i = h; i < len; i++) {
                int temp = a[i];
                int index = i;
                while (index - h >= 0 && a[index - h] > temp) {
                    a[index] = a[index - h];
                    index = index - h;
                }
                a[index] = temp;
            }
            h = h / 3;
        }
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值