TAOCP-1.2.10_求极大值
1. 算法M(求极大值)
给定\(n\)个元素\(X[1], X[2], ..., X[n]\), 我们将求\(m\)和\(j\)使得:
\(m=X[j]=max_{1 \le i \le n}X[i]\),其中\(j\)是满足这个关系的最大下标。
M1. [初始化] 置 \(j \gets n, k \gets n - 1, m \gets X[n]\)。(在算法期间,我们将有\(m = X[j] = max_{k < i \le n}X[i]\)。)
M2. [全部试过了?] 如果\(k = 0\),则算法终止。
M3. [比较] 如果\(X[k] \le m\),则转到 M5。
M4. [改变m] 置\(j \gets k, m \gets X[k]\)。(这个m的值是一个新的当前的极大值。)
M5. [减少k] k 减 1 并返回 M2
1.1 C实现
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#define ARRAY_SIZE 16
int32_t cycles;
int maximum(int x[], int n)
{
int j, k, m;
j = n;
k = n - 1;
m = x[n];
while (k) {
cycles++;
//printf("x[%d] = %d, j = %d, k = %d, m = %d\n", k, x[k], j, k, m);
if (x[k] <= m) {
k--;
if (k == 0)
break;
} else {
j = k;
m = x[k];
}
}
return m;
}
int main(void)
{
int array[ARRAY_SIZE];
int i;
int ret;
srand((unsigned)time(NULL));
for (i = 0; i < ARRAY_SIZE; i++) {
array[i] = random() % 1000;
}
ret = maximum(array, ARRAY_SIZE - 1);
printf("Array is: \n");
for (i = 0; i < ARRAY_SIZE; i++) {
if ((i > 0) && (i % 8) == 0)
printf("\n");
printf("%d\t", array[i]);
}
printf("\n\nThe maximum of array is %d, cycles is %d\n", ret, cycles);
return 0;
}
1.2 运行结果:
# make
gcc -Wall -O3 -g m.c -o m
# ./m
Array is:
540 475 412 567 458 974 837 205
461 958 227 659 105 658 110 110
The maximum of array is 974, cycles is 18
1.3 性能分析
当n很大时,算法M的执行次数近似于\(\ln n\)