测量一些排序算法的时间复杂度

时间:2015-01-02 17:08:43

标签: java arrays algorithm sorting time-complexity

我正在用Java编写一个演示类来分析以下排序算法:

  1. 插入排序
  2. 选择排序
  3. 冒泡
  4. 归并
  5. 快速排序
  6. 我在另一个名为Sort的类中实现了静态方法。

    我希望通过使用omicron公式确定运算符和分析komplexity来比较每种算法的Best,Average和Worst-Case。

    在演示类中,我只想确定每个算法需要按照数组中最佳,平均和最坏情况顺序对不同长度的整数数组进行排序的时间(以纳秒为单位)。 p>

            //Best-Case
        int[] arrbc0 = {1};
        int[] arrbc1 = {1, 2};
        int[] arrbc2 = {1, 2, 3};
        int[] arrbc3 = {1, 2, 3, 4, 5};
        int[] arrbc4 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] arrbc5 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
    
        //Average-Case
        int[] arrac1 = {1, 2};
        int[] arrac2 = {3, 1, 2};
        int[] arrac3 = {4, 2, 3, 1, 5};
        int[] arrac4 = {9, 1, 10, 6, 2, 4, 8, 3, 7, 5};
        int[] arrac5 = {13, 12, 1, 15, 5, 6, 7, 2, 14, 10, 3, 8, 4, 9, 11};
    
        //Worst-Case
        int[] arrwc1 = {2, 1};
        int[] arrwc2 = {3, 2, 1};
        int[] arrwc3 = {5, 4, 3, 2, 1};
        int[] arrwc4 = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
        int[] arrwc5 = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
    
        //InsertionSort:
        isNanoTime(arrbc0); //first load
        isNanoTime(arrbc1);
        isNanoTime(arrbc2);
        //...
    
        public static void isNanoTime(int[] arr) {
        long a1 = System.nanoTime();
        Sort.insertionSort(arr);
        long a2 = System.nanoTime() - a1;
        System.out.println(a2);
        }
    

    现在我有一些问题:

    1. 我可以将这些数组用于这些算法的所有最佳,平均和最差情况,或者具有f.e. MergeSort的最坏情况另一个订单?!
    2. 在对数组进行排序后,是否有一种简单的方法可以解开数组?
    3. 无论如何,这是确定时间复杂性的“正确方法”(也许有人有更好的主意)?

3 个答案:

答案 0 :(得分:1)

  1. 你的阵列太短了:任何"现代"几乎没有时间。即使在最糟糕的情况下,CPU也要对它们进行排序
  2. 要根据输入的随机性进行相关的时间变化,您需要设置一个固定的输入大小,并为您提供可测量的时间(可能是秒数)
  3. 您可能需要生成一组数千个随机数组,可能会为此集添加一些特定数组(已排序,反向排序,......)。然后,您可以在此集合中的每个阵列上运行每个算法,并测量对它们进行排序所需的时间。这样你就可以为每个算法获得一个很好的分布图,你可以在其中看到每个算法的行为(冒泡排序非常高,而heapsort非常稳定......)。对于其他算法,一种算法的最差输入不一定相同,因此设置。

答案 1 :(得分:0)

  1. 此类数组可以显示InsertionSort和BubbleSort的最差和最佳情况。 MergeSort和SelectionSort的典型实现对于所有阵列具有相同的复杂性。最简单的QuickSort实现的最坏情况是排序(或反向排序)数组 Wiki page with useful table
    请注意,这些数组太短,无法发现运行时间的任何差异。使数组具有10 ^ 3-10 ^ 6个元素(分别用于慢速和快速算法)。

  2. 查看Fisher-Yates shuffle获取随机序列

答案 2 :(得分:0)

@MBo @Jean Logeart

您如何看待这个:

//Main:
for(int n = 100_000; n <= 1_000_000; n = n + 100_000) {
    //f.e. average case of insertion sort:
    int[] arr = randomArray(n);
    insertionSortWithRuntime(arr);
}

/**
 * For best cases using sorted numbers.
 * @param n- the length in which the array should be created.
 * @return
 */
public static int[] sortedArray(int n) {
    int[] arr = new int[n];

    for (int i = 0; i < n; i++) {
        arr[i] = i;
    }
    return arr;
}

/**
 * For average cases using random numbers.
 * @param n - the length in which the array should be created.
 * @return
 */
public static int[] randomArray(int n) {
    int[] arr = new int[n];

    for (int i = 0; i < n; i++) {
        arr[i] = (int) (Math.random() * 9 + 1);
    }
    return arr;
}

/**
 * For worst cases using reversed sorted numbers.
 * @param n - the length in which the array should be created.
 * @return
 */
public static int[] reversedSortedArray(int n) {
    int[] arr = new int[n];

    int length = n - 1;

    for (int i = 0; i < n; i++) {
        arr[i] = length;
        length--;
    }
    return arr;
}

你有没有想过这样?