我正在尝试计算使用选择排序算法对已经排序的数组(例如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
第一个已经排序的数组需要更多时间。这没有意义。我花了很多时间调试并尝试打印这些数组来查看它们,但没有想出来。
答案 0 :(得分:1)
您的代码中存在多个问题:
<stdio.h>
和<time.h>
B
和C
。我建议您使用具有静态或动态(堆)存储的数组,而不是自动避免堆栈溢出。sort
缓冲区溢出:for (int i = 0; i <= n; i++)
它应该是i < n
。关于时间安排,您的排序函数selectionsort
执行完全相同数量的比较和交换,除了结果,因此时间必然接近,只有A[k] < A[min]
的结果不同。在排序的情况下,此测试始终为false,并且对于其他情况而言会有所不同,真实案例的数量从n - 2
线性减少到0
。根据为此循环生成代码的方式以及CPU的分支预测功能的效率,您可能会获得一个或另一个的小优势,只有谨慎的时间才会告诉您。从你的结果来看,分支的成本从来不会超过额外的min = i
商店。
你的时间实际上非常接近(差异不到6%)。我得到了相同的结果,但是同一个程序的多次运行给出了相同数量级的时间变化......很难得出明确的结论。
不同的编译器和不同的CPU可能会产生相反的结果。
检查已经排序的输入的初始传递是值得的,因为它对诸如insertionsort
之类的低效排序的时间添加非常少。它会使这些特殊情况几乎瞬间完成:0.00001
,0.00002
和0.00005
为您的例子。
更有效的排序算法也会使这些时间相形见绌:heapsort,mergesort,quicksort,radix sort应该在你的设置尺寸上加快100到1000次次。