【发布时间】:2014-10-09 02:31:32
【问题描述】:
算法复杂度的计算让我很困惑。对于一项任务,我们得到以下函数并要求找出它的复杂性。
int selectkth(int a[], int k, int n) {
int i, j, mini, tmp;
for (i = 0; i < k; i++) {
mini = i;
for (j = i+1; j < n; j++)
if (a[j]<a[mini])
mini = j;
tmp = a[i];
a[i] = a[mini];
a[mini] = tmp;
}
return a[k-1];
}
赋值本身要求“找出用于在无序整数数组中查找第 k 个最小整数的函数的复杂度。”
此外,我们还被要求编写 f 函数和 g 函数。
据我了解,对于 f 函数,我会在函数中添加所有的赋值和操作。我是否在这个 f 函数中包含变量 k 或 n?
作为最佳猜测,我会说 f(n) = 6n + 4(n^2),因为在第一个 for 循环中循环了 6 个操作,然后在嵌套的 for 循环中循环了 4 个操作。
为了进一步理解,这个函数的大O复杂度会是O(n^2)吗?我这么说是因为有一个嵌套的 for 循环,这意味着最坏的情况是每次都要遍历每个项目。
如果我不清楚,我深表歉意。我对它的工作原理感到很困惑。
【问题讨论】:
-
你是正确的,两个嵌套循环意味着
O(n^2),我试图提出一个方程来显示指令的确切数量是愚蠢的,因为有些会变成不止一个 CPU 指令,并且有些会被编译器优化出来。 -
两个嵌套循环并不一定意味着
O(n^2)。这里外循环从 0 到 k-1,这可能导致O(kn)而不是O(n^2)。 (我说“可能”是因为我在没有正式证据的情况下进行猜测。)准确使用变量很重要,不要总是将思维过程简化为“两个循环 = 二次 = O(n^2)”。跨度> -
内循环执行
(n-1) + (n-2) + ... + (n-k)次,明显是O(kn)。 -
@J.F.Sebastian 是的,但
O(kn)比O(n^2)更严格。也可以说时间复杂度是O(n^3)并且是正确的,但这将是一个不必要的宽松上限。 -
是的,它是。如果
k=1则函数以线性时间运行。重要的是在分析此函数时捕获k,而不是用n替换它。如果结果中没有k,那么您将无法查看函数的运行时间如何随着k的变化而变化。
标签: c++ algorithm time-complexity