【发布时间】:2021-08-21 09:03:56
【问题描述】:
我使用两个函数实现了 max 函数(给定一个数组,找到最大值):max,它是 O(n) 和 mergeMax,我希望它是 O(lg n),通过使用分而治之的方法。我原以为随着 n 的增加,mergeMax 会胜出,但令我惊讶的是,它每次都被 max 函数击败。我说 mergeMax 是 O(lg N) 有错吗?这是C中的代码:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int maxValue = 0;
void mergeMax(int items[], int low, int high)
{
if (high == low)
{
if (items[low] > maxValue) maxValue = items[low];
return;
}
if (high - low == 1)
{
if (items[low] > items[high])
{
if (items[low] > maxValue) maxValue = items[low];
}
else
{
if (items[high] > maxValue) maxValue = items[high];
}
return;
}
int middleValue = (low + high) / 2;
mergeMax(items, low, middleValue);
mergeMax(items, middleValue + 1, high);
}
int max(const int items[], int itemCount)
{
int max = 0;
for (int i = 0; i < itemCount; i++)
{
if (items[i] > max) max = items[i];
}
return max;
}
int main(void)
{
int itemCount = 2000000;
printf("Generating...\n");
int items[itemCount];
srand(time(0));
for (int i = 0; i < itemCount; i++)
{
items[i] = rand() % ((4294967295/2) + 1);
}
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
mergeMax(items, 0, itemCount - 1);
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
printf("O(lg n) time in microseconds: %lu. Result: %d\n", delta_us, maxValue);
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
int maximum = max(items, itemCount);
clock_gettime(CLOCK_MONOTONIC_RAW, &end);
delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;
printf("O(n) time in microseconds: %lu. Result: %d\n", delta_us, maximum);
}
【问题讨论】:
-
提示:你确定你可以在亚线性时间内找到数组中的最大值吗?没有特殊结构?你不应该至少看看所有元素吗?
-
因为你需要检查所有元素(假设数组没有排序),那么你不能做得比 O(n) 更好。
-
@Someprogrammerdude 哎呀!你说得对。我编辑了它。
-
mergeMax()和max()都是O(n)...max()比mergeMax()更简单,所以需要的时间更少。
标签: c complexity-theory divide-and-conquer