【问题标题】:the running time for an already sorted array being sorted by selection sort algorithm Vs the time for a reversed sorted array being sorted通过选择排序算法对已排序数组进行排序的运行时间与对反向排序数组进行排序的时间
【发布时间】:2017-07-16 21:12:50
【问题描述】:

我正在尝试计算使用选择排序算法对已排序的数组(例如 1、2、3、4、5、..)进行排序的运行时间以及使用该算法对反向数组进行排序的时间(例如 5,4,3,2..)。 我发现的奇怪之处在于,在我的计算机上,对已排序的数组进行排序比对反向数组进行排序需要更多时间。根据我了解到的情况,我认为应该反过来。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void selectionsort(int A[], int n) {
    int min;
    for (int i = 0; i < n - 1; i++) {
        min = i;
        for (int k = i + 1; k < n; k++) {
            if (A[k] < A[min]) {
                min = k;
            }
        }
        int temp = A[i];
        A[i] = A[min];
        A[min] = temp;
    }
}

void sort(int A[], int n) {
    for (int i = 0; i < n; i++) {
        A[i] = i + 1;
    }
}

void resver_sort(int A[], int n) {
    for (int i = 0; i < n; i++) {
        A[i] = n - i;
    }
}

int main() {
    clock_t start, end;
    double cpu_time_used;

    int A[20000] = { 0 };
    int B[40000] = {0};
    int C[100000] = {0};

    printf("Selection Sort, Sorted Array\n");

    sort(A, 20000);
    start = clock(); // start the clock
    selectionsort(A, 20000);
    end = clock(); // stop the clock
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; // calculate the actual time used
    printf("array size:20000 time:%f\n", cpu_time_used);

    sort(B, 40000);
    start = clock();
    selectionsort(B, 40000);
    end = clock();
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
    printf("array size:40000 time:%f\n", cpu_time_used);

    sort(C, 100000);
    start = clock();
    selectionsort(C, 100000);
    end = clock();
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
    printf("array size:100000 time:%f\n", cpu_time_used);

    printf("Selection Sort, reverse sorted Array\n");

    resver_sort(A, 20000);
    start = clock(); 
    selectionsort(A, 20000);
    end = clock(); 
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC; 
    printf("array size:20000 time:%f\n", cpu_time_used);

    resver_sort(B, 40000);
    start = clock();
    selectionsort(B, 40000);
    end = clock();  
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
    printf("array size:40000 time:%f\n", cpu_time_used);

    resver_sort(C, 100000);
    start = clock();    
    selectionsort(C,100000);
    end = clock();   
    cpu_time_used = ((double)(end - start)) / CLOCKS_PER_SEC;
    printf("array size:100000 time:%f\n", cpu_time_used);
}

结果是

Selection Sort, Sorted Array
array size:20000 time:0.530281
array size:40000 time:2.109836
array size:100000 time:13.197117
Selection Sort, reverse sorted Array
array size:20000 time:0.500338
array size:40000 time:2.016468
array size:100000 time:12.830447
Program ended with exit code: 0

第一个已经排序的数组需要更多时间。这没有意义。我花了很多时间调试并尝试打印这些数组以查看它们,但没有弄明白。

【问题讨论】:

  • 做几千次,得到平均时间。还要对优化的构建进行这种测量。
  • 您能否考虑重新缩进您的代码,使其真正可读。
  • @Antti Haapala 抱歉,我不知道您无法阅读。我已经修改过了。:)
  • 谢谢,现在好多了!
  • 好的,我测试过了。使用 -03 时,运行时间减少了 67 %。此外,第一个排序操作比第二个排序操作慢,无论哪个先出现。一定与缓存和分支预测有关。

标签: c arrays sorting time selection-sort


【解决方案1】:

您的代码中存在多个问题:

  • 您不包括&lt;stdio.h&gt;&lt;time.h&gt;
  • 您没有定义数组BC。我建议您使用具有静态或动态(堆)存储的数组,而不是自动的,以避免堆栈溢出。
  • 函数sort 有一个缓冲区溢出:for (int i = 0; i &lt;= n; i++) 它应该是i &lt; n

关于时间,您的排序函数selectionsort 执行完全相同数量的比较和交换,除了结果之外,时间必然接近,只是A[k] &lt; A[min] 的结果不同。在排序的情况下,这个测试总是错误的,而在另一种情况下,真实情况的数量从n - 2线性减少到0。根据此循环的代码生成方式以及 CPU 的分支预测功能的效率,您可能会从中获得一点优势,只有仔细的时间安排才能告诉您这一点。从您的结果看来,分店的成本永远不会超过额外的min = i 商店的补偿。

您的时间实际上非常接近(相差不到 6%)。我得到了相同的结果,但是同一程序的多次运行给出了相同数量级的时间变化......很难得出明确的结论。

不同的编译器和不同的 CPU 可能会产生相反的结果。

检查已经排序的输入的初始通过是值得的,因为它对像insertionsort 这样的低效排序的时间增加很少。这将使这些特殊情况几乎瞬间完成:0.000010.000020.00005 以您为例。

更高效的排序算法也将使这些时间相形见绌:堆排序、归并排序、快速排序、基数排序在您的集合大小上都应该快 100 到 1000 倍。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    • 2019-12-10
    • 1970-01-01
    相关资源
    最近更新 更多