java--希尔排序与直接插入排序的执行时间比较

225 阅读2分钟

希尔排序与直接插入排序的执行时间比较

创建100000(十万)个有序数据,按倒序来测试测试希尔排序和插入排序的执行时间:

  • 具体代码如下:

直接插入排序:

//直接插入排序
class Insertion {
    //对数组a中的元素进行排序
    public static void sort(Comparable[] a){
        for (int i = 0; i < a.length-1; i++) {
            for (int j = i+1; j > 0; j--) {
                //当前作比较的元素为a[i+1],若a[i+1]小于a[i],则将a[i]和a[i+1]互换
                if(greater(a[j-1],a[j])){
                    exchange(a,j-1,j);
                    //交换元素
                }
                else{
                    //前面没有比a[j]更大的元素,说明前面的元素都已排好序,则结束循环
                    break;
                }
            }
        }
    }

    //比较v元素是否大于w元素
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }

    //数组元素i和j交换
    private static void exchange(Comparable[] a,int i,int j){
        Comparable temp;
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

public class InsertionTest {
    public static void main(String[] args) {
        final int MAX =100000;//十万

        //创建一个容量为十万(100000)的数组
        Integer[] arr = new  Integer[MAX];

        int count=MAX;

        //将1~100000按倒序存入数组中
        for (int i = 0; i <MAX; i++) {
            arr[i]=count;
            count--;
        }

        testInsertion(arr);
    }

    //测试插入排序
    public static void testInsertion(Integer[] a){
        //1、获取执行之前的时间
        long start=System.currentTimeMillis();
        //执行算法代码
        sort.Insertion.sort(a);
        //3、获取执行之后的时间
        long end=System.currentTimeMillis();
        //算出程序执行的时间并且输出
        System.out.println("插入排序执行的时间为:"+(end-start)+"毫秒");
    }
}

测试结果:

image.png


希尔排序:

希尔排序的方式是对待排序数组先进行一个宏观调控,让整个数组趋向于有序化,然后我们只需对数组中的元素进行微调即可完成排序。

//希尔排序
class Shell {
    //对数组a中的元素进行排序
    public static void sort(Comparable[] a){
        int h=(a.length/2)+1;
        //为h赋初始值:数组长度的一半再加1

        while(h>=1){
            //i必须小于a.length-h
            //因为当i>=a.length-h时,j=i+h会造成溢出
            for (int i = 0; i < a.length-h; i++) {
                for (int j = i+h; j >=h; j-=h) {
                    //待插入的元素是a[j],比较a[j]和a[j-h]
                    if(greater(a[j-h],a[j])){
                        //交换元素
                        exchange(a,j,j-h);
                    }
                    else{
                        //前面没有比a[j]更大的元素,说明前面的元素都已排好序,则结束循环
                        break;
                    }
                }
            }
            h=h/2;
            //h=h/2可以保证最后h会等于1
        }
    }

    //比较元素v和w的大小
    private static boolean greater(Comparable v,Comparable w){
        return v.compareTo(w)>0;
    }

    //交换索引为a[i]和a[j]的值
    private static void exchange(Comparable[] a,int i,int j){
        Comparable temp;
        temp=a[i];
        a[i]=a[j];
        a[j]=temp;
    }
}

public class ShellTest {
    public static void main(String[] args) {
        final int MAX =100000;//十万

        //创建一个容量为十万(100000)的数组
        Integer[] arr = new  Integer[MAX];

        int count=MAX;

        //将1~100000按倒序存入数组中
        for (int i = 0; i <MAX; i++) {
            arr[i]=count;
            count--;
        }

        testShell(arr);
    }

    //测试希尔排序
    public static void testShell(Integer[] a){
        //1、获取执行之前的时间
        long start= System.currentTimeMillis();
        //2、执行算法代码
        sort.Shell.sort(a);
        //3、获取执行之后的时间
        long end=System.currentTimeMillis();
        //4、算出程序执行的时间并输出
        System.out.println("希尔排序执行的时间为:"+(end-start)+"毫秒");
    }
}

测试结果:

image.png

结论:

  • 当数据部分有序时,直接插入排序的效率略高于 希尔排序;
  • 当测试数据很大或者混乱度较高时,希尔排序的效率远大于直接插入排序。