选择问题
来自:【数据结构与算法分析——C语言描述】练习1.1
问题描述:编写一个程序解决选择问题。令k = N / 2。画出表格显示你的程序对于N为不同值时的运行时间。
(设有一组 N 个数确定其中第 k 个最大者,称选择问题(selection problem))
思路:读入前 k 个数到临时数组 tmp(并按降序排列)。然后逐个读取后续数字 X ,当 X 大于第 k 个数时,将其加入数组 tmp(并按降序排列)。最后返回位置 k - 1 上的值。
实现:
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 10000 int select(int arr[], int n, int k); int main(void) { int * arr; int value; clock_t elapse; srand((unsigned)time(NULL)); arr = (int *)malloc(sizeof(int) * N);; for (int j = 0; j < N; j++) { arr[j] = rand() % 100000; printf("%d ", arr[j]); } putchar('\n'); elapse = clock(); value = select(arr, N, N / 2); elapse = clock() - elapse; printf("Value: %d, elapsed: %.4lfs\n", value, (double)elapse / 1000); free(arr); system("pause"); return 0; } /* 选择数组中第k个最大者 */ int select(int arr[], int n, int k) { int * tmp; int i, j, ret; tmp = (int *)malloc(sizeof(int) * k); tmp[0] = arr[0]; for (i = 1; i < k; i++) //读入k个元素并降序排列 { tmp[i] = arr[i]; for (j = i; j > 0; j--) { if (arr[i] > tmp[j - 1]) { tmp[j] = tmp[j - 1]; tmp[j - 1] = arr[i]; } } } for (i = k; i < n; i++) //读入arr[k] { if (tmp[k - 1] < arr[i]) { tmp[k - 1] = arr[i]; for (j = k - 1; j > 0; j--) { if (arr[i] > tmp[j - 1]) { tmp[j] = tmp[j - 1]; tmp[j - 1] = arr[i]; } } } } ret = tmp[k - 1]; free(tmp); return ret; }
记录:
N值 | 耗时(秒) |
10000 |
0.0820 |
20000 |
0.3260 |
30000 |
0.7320 |
40000 |
1.3080 |
50000 |
2.0320 |
60000 |
2.9390 |
70000 |
3.9990 |
80000 |
5.2160 |
90000 |
6.6530 |
100000 |
8.1610 |
小记:该算法在输入数据量较少时,可以在合理的时间内给出结果。如果数据量过大,这个算法就不切实际了。