为什么选择排序比气泡排序快?

时间:2018-09-22 01:09:56

标签: java arrays sorting bubble-sort selection-sort

使用Java我已经进行了一项实验,以确定哪种排序方法(气泡或选择)的运行速度更快。程序提示用户输入数字n,该数字是要排序的数组中的项目数。然后,它会创建并排序500个此大小的不同数组,并对运行次数进行排序,以得出使用这两种排序方法进行排序的平均时间。我使用500、1000和2500作为n的测试输入。我的以下结果显示选择排序比气泡排序运行得快,但是两种算法的时间复杂度均为O(n ^ 2),那么为什么选择排序运行得这么快?

TimeBubbleSort类

public class TimeBubbleSort {
    public static void main(String[] args) {

        System.out.print("Enter a number of items in array: ");
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        long start_time = 0;
        long end_time = 0;
        long running_time = 0;
        long final_time = 0;
        BubbleSort bubbleSort = new BubbleSort();

        for(int i = 0; i < 500; i++) {
            int[] array = new int[n];
            for(int j = 0; j < array.length; j++) {
                array[j] = (int)(Math.random() * n) + 1;
            }
            start_time = System.nanoTime();
            bubbleSort.bubbleSort(array);
            end_time = System.nanoTime();
            running_time = end_time - start_time;
            final_time = final_time + running_time;
        }
        System.out.println("The average time of each array took " + 
(final_time / 500) + " nanoseconds");
    }
}

BubbleSort类

public class BubbleSort {

    void bubbleSort(int[] arr) {
        int n = arr.length;
        int temp = 0;
        for (int i = 0; i < n; i++)
            for (int j = 1; j < (n - i); j++)
                if (arr[j - 1] > arr[j]) {
                    temp = arr[j - 1];
                    arr[j - 1] = arr[j];
                    arr[j] = temp;
                }
    }

    void printArray(int[] arr) {
        int n = arr.length;
        for (int i = 0; i < n; ++i)
            System.out.print(arr[i] + " ");
        System.out.println();
    }
}

TimeSelectionSort类

public class TimeBubbleSort {
    public static void main(String[] args) {

        System.out.print("Enter a number of items in array: ");
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();

        long start_time = 0;
        long end_time = 0;
        long running_time = 0;
        long final_time = 0;
        SelectionSort selectionSort = new SelectionSort();

        for(int i = 0; i < 500; i++) {
            int[] array = new int[n];
            for(int j = 0; j < array.length; j++) {
                array[j] = (int)(Math.random() * n) + 1;
            }
            start_time = System.nanoTime();
            selectionSort.selectionSort(array);
            end_time = System.nanoTime();
            running_time = end_time - start_time;
            final_time = final_time + running_time;
        }
        System.out.println("The average time of each array took " + 
(final_time / 500) + " nanoseconds");
    }
}

SelectionSort类

public class SelectionSort {
    void sort(int arr[]) {
        int n = arr.length;

        for (int i = 0; i < n - 1; i++) {
            int min_idx = i;
            for (int j = i + 1; j < n; j++)
                if (arr[j] < arr[min_idx])
                    min_idx = j;

            int temp = arr[min_idx];
            arr[min_idx] = arr[i];
            arr[i] = temp;
        }
    }

    void printArray(int arr[]) {
        int n = arr.length;
        for (int i=0; i<n; ++i)
            System.out.print(arr[i]+" ");
        System.out.println();
    }
}

使用冒泡排序的结果

数组大小为500:耗时284,979纳秒

数组大小为1000:耗时960,067纳秒

数组大小为2500:花费了7448865纳秒

使用选择排序的结果

数组大小为500:耗时107,035纳秒

数组大小为100:花费了342,464纳秒

数组大小为2500:花费了1,880,215纳秒

2 个答案:

答案 0 :(得分:1)

首先,与系统时间进行比较不是分析两种算法的时间复杂性的正确方法,因为请记住-您的程序不是系统上运行的唯一程序。因此,即使算法和输入相同,两个运行时间也可能完全不同。

现在回答您的问题,与每次迭代中仅在最后一步交换的选择排序相比,气泡排序的交换次数更多。所以这可能是原因。

这两种算法具有相同的时间复杂度,并不意味着它们的运行时间会相同。首先,它们的时间复杂度大约是最大的,这是最大的因素。在上述两种情况下,最大因子都是n ^ 2,但是还有其他较小的n次幂和常数会导致差异。

答案 1 :(得分:-1)

虽然您在这里使用系统计时器很困难,但是您正在做足够的尝试,我认为这不是罪魁祸首。我也很难相信交换会消耗总时间的近2/3,这是Brij Raj Kishore正确回答所需的时间。

虽然循环结构并不完全相同,但两者都运行了大约n ^ 2/2次,因此两者之间也不应有太大差异。

因此,我认为需要进行更多挖掘。我不知道您的系统上有哪些可用的探查器,但是除非有人在这里找到大的东西,否则这将是我的下一步。看看您的日常工作实际上是在花时间。