为什么我的插入排序比合并排序快?

时间:2018-09-20 21:29:24

标签: java algorithm sorting

我正在为我的数据结构类进行分配,但我不知道为什么我的插入排序比合并排序快得多。我发布了2个版本,其中一个带有他的快速插入排序代码,一个版本与我稍后发现的慢版本。我的教授真的很惊讶,说我很理解。我相信这是因为我避免了一项耗时的工作,但是我无意间做了此事,而且我仍在尝试学习时间的复杂性,这使我感到困惑。

(慢速版本)

package sorting; 

import java.util.*;

public class Sort {

    public static int[] insertion_sort (int[] array) {

    int i;

        for (int j = 1; j < array.length; j++) {
            int key = array[j-1];  // assigns the key to the first value of the array  

            i = j-1; // i is always one less than j

            while (i >0 && array[i] > key) {
                array[i+1] = array[i];
                i = i -1;
            }
                array[i+1] = key;
        }



        return array;
    }

    public static int[] merge_sort (int[] array, int p, int r) {

        if (p < r) {
            int q = (p + r) /2;
            Sort.merge_sort(array, p, q);
            Sort.merge_sort(array, q+1, r);
            Sort.merge(array, p, q, r);
        }

        return array;
    }

    public static int[] merge (int[] array, int p, int q, int r) {
        int n1  = q - p +1;
        int n2 = r - q;
        int[] L = new int[n1+1];
        int[] R = new int [n2+1];

        for (int i = 0; i < n1; i++) {
            L[i] = array[p+i];

        }

        for (int j = 0; j <n2; j++) {
            R[j] = array[q+j+1];
        }

        L[n1] = Integer.MAX_VALUE;
        R[n2] = Integer.MAX_VALUE;

        int i = 0; 
        int j = 0;

        for (int k = p; k<= r; k++) {
            if (L[i] <= R[j]) {
                array[k] = L[i];
                i++;
            }

            else {
                array[k] = R[j];
            }
        }
        return array;
    }

    /*
     * n: the size of the output array
     * k: the maximum value in the array
     */
    public static int[] generate_random_array (int n, int k) {
        List<Integer> list;
        int[] array;
        Random rnd;

        rnd = new Random(System.currentTimeMillis());

        list = new ArrayList<Integer> ();
        for (int i = 1; i <= n; i++) 
            list.add(new Integer(rnd.nextInt(k+1)));

        Collections.shuffle(list, rnd);

        array = new int[n];
        for (int i = 0; i < n; i++) 
            array[i] = list.get(i).intValue();

        return array;
    }

    /*
     * n: the size of the output array
     */
    public static int[] generate_random_array (int n) {
        List<Integer> list;
        int[] array;

        list = new ArrayList<Integer> ();
        for (int i = 1; i <= n; i++) 
            list.add(new Integer(i));

        Collections.shuffle(list, new Random(System.currentTimeMillis()));

        array = new int[n];
        for (int i = 0; i < n; i++) 
            array[i] = list.get(i).intValue();

        return array;
    }

    /*
     * Input: an integer array
     * Output: true if the array is acsendingly sorted, otherwise return false
     */
    public static boolean check_sorted (int[] array) {
        for (int i = 1; i < array.length; i++) {
            if (array[i-1] > array[i])
                return false;
        }
        return true;
    }

    public static void print_array (int[] array) {
        for (int i = 0; i < array.length; i++)
            System.out.print(array[i] + ", ");
        System.out.println();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("Insertion sort starts ------------------");
        for (int n = 100000; n <= 1000000; n=n+100000) {
            int[] array = Sort.generate_random_array(n);
            long t1 = System.currentTimeMillis();
            array = Sort.insertion_sort(array);
            long t2 = System.currentTimeMillis();
            long t = t2 - t1;
            boolean flag = Sort.check_sorted(array);
            System.out.println(n + "," + t + "," + flag);
        }
        System.out.println("Insertion sort ends ------------------");


        System.out.println("Merge sort starts ------------------");
        for (int n = 100000; n <= 1000000; n=n+100000) {
            int[] array = Sort.generate_random_array(n);
            //Sort.print_array(array);
            long t1 = System.currentTimeMillis();
            array = Sort.merge_sort(array, 0, n-1);
            long t2 = System.currentTimeMillis();
            long t = t2 - t1;
            //Sort.print_array(array);
            boolean flag = Sort.check_sorted(array);
            System.out.println(n + "," + t + "," + flag);
        }
        System.out.println("Merge sort ends ------------------");
    }

}

(慢速版本)


import java.util.*;

public class Sort {

    public static int[] insertion_sort (int[] array) {

    int i;

        for (int j = 1; j < array.length; j++) {
            int key = array[j];  // assigns the key to the first value of the array  

            i = j-1; // i is always one less than j

            while (i >=0 && array[i] > key) {
                array[i+1] = array[i];
                i = i -1;
            }
                array[i+1] = key;
        }



        return array;
    }

    public static int[] merge_sort (int[] array, int p, int r) {

        if (p < r) {
            int q = (p + r) /2;
            Sort.merge_sort(array, p, q);
            Sort.merge_sort(array, q+1, r);
            Sort.merge(array, p, q, r);
        }

        return array;
    }

    public static int[] merge (int[] array, int p, int q, int r) {
        int n1  = q - p +1;
        int n2 = r - q;
        int[] L = new int[n1+1];
        int[] R = new int [n2+1];

        for (int i = 0; i < n1; i++) {
            L[i] = array[p+i];

        }

        for (int j = 0; j <n2; j++) {
            R[j] = array[q+j+1];
        }

        L[n1] = Integer.MAX_VALUE;
        R[n2] = Integer.MAX_VALUE;

        int i = 0; 
        int j = 0;

        for (int k = p; k<= r; k++) {
            if (L[i] <= R[j]) {
                array[k] = L[i];
                i++;
            }

            else {
                array[k] = R[j];
            }
        }
        return array;
    }

    /*
     * n: the size of the output array
     * k: the maximum value in the array
     */
    public static int[] generate_random_array (int n, int k) {
        List<Integer> list;
        int[] array;
        Random rnd;

        rnd = new Random(System.currentTimeMillis());

        list = new ArrayList<Integer> ();
        for (int i = 1; i <= n; i++) 
            list.add(new Integer(rnd.nextInt(k+1)));

        Collections.shuffle(list, rnd);

        array = new int[n];
        for (int i = 0; i < n; i++) 
            array[i] = list.get(i).intValue();

        return array;
    }

    /*
     * n: the size of the output array
     */
    public static int[] generate_random_array (int n) {
        List<Integer> list;
        int[] array;

        list = new ArrayList<Integer> ();
        for (int i = 1; i <= n; i++) 
            list.add(new Integer(i));

        Collections.shuffle(list, new Random(System.currentTimeMillis()));

        array = new int[n];
        for (int i = 0; i < n; i++) 
            array[i] = list.get(i).intValue();

        return array;
    }

    /*
     * Input: an integer array
     * Output: true if the array is acsendingly sorted, otherwise return false
     */
    public static boolean check_sorted (int[] array) {
        for (int i = 1; i < array.length; i++) {
            if (array[i-1] > array[i])
                return false;
        }
        return true;
    }

    public static void print_array (int[] array) {
        for (int i = 0; i < array.length; i++)
            System.out.print(array[i] + ", ");
        System.out.println();
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("Insertion sort starts ------------------");
        for (int n = 100000; n <= 1000000; n=n+100000) {
            int[] array = Sort.generate_random_array(n);
            long t1 = System.currentTimeMillis();
            array = Sort.insertion_sort(array);
            long t2 = System.currentTimeMillis();
            long t = t2 - t1;
            boolean flag = Sort.check_sorted(array);
            System.out.println(n + "," + t + "," + flag);
        }
        System.out.println("Insertion sort ends ------------------");


        System.out.println("Merge sort starts ------------------");
        for (int n = 100000; n <= 1000000; n=n+100000) {
            int[] array = Sort.generate_random_array(n);
            //Sort.print_array(array);
            long t1 = System.currentTimeMillis();
            array = Sort.merge_sort(array, 0, n-1);
            long t2 = System.currentTimeMillis();
            long t = t2 - t1;
            //Sort.print_array(array);
            boolean flag = Sort.check_sorted(array);
            System.out.println(n + "," + t + "," + flag);
        }
        System.out.println("Merge sort ends ------------------");
    }

}

0 个答案:

没有答案