该算法的复杂度函数
Posted
技术标签:
【中文标题】该算法的复杂度函数【英文标题】:Complexity function of this algorithm 【发布时间】:2016-04-12 01:55:01 【问题描述】:我正在尝试找到该算法的最坏情况复杂度函数,将比较语句视为最相关的操作。那是if
和else if
总是在循环下执行的时候,所以函数是2*循环执行次数。
由于变量i
每次复杂度可能为 O(log n) 时都会增加一个更大的数字,但我如何找到执行的准确次数?谢谢。
int find ( int a[], int n, int x )
int i = 0, mid;
while ( i < n )
mid = ( n + i ) / 2;
if ( a[mid] < x )
n = mid;
else if ( a[mid] > x )
i = mid + 1;
else return mid;
return 0;
【问题讨论】:
每次执行循环大小减少一半。所以如果你有 n 个元素,那么 pow(2,x) = n。其中 x = 迭代次数。(因为在最坏的情况下,循环在 i >=n 时终止)。所以 x = log2 (n)。 “因为变量 i 每次都增加一个更大的数字” - 不,不是:如果它正在增加(因为x
仍然大于 @987654326 @),每次都会减少一半 - 即每次增加一个较小的数字。无论如何......“可能O(log n)”是正确的......更具体地说是O(log-base-2(N))。 “但是我如何找到确切的执行次数?” 要找到“更糟糕的情况复杂度函数”,您不需要确切的执行次数;复杂性分析忽略了常数因素,需要不断减半搜索是最坏的情况。
谢谢各位,当 else if 为真时,你能解释一下为什么 log(2,n) 吗?当 if 语句为真时,我可以看到。
【参考方案1】:
定性理解
好吧,让我们尝试看看循环不变量,以了解这个函数要运行多长时间。
我们可以看到该函数会继续执行代码,直到满足while(i < n) ...
这个条件。
我们还要注意,在这个while
循环中,i
或 n
总是被变异为mid
的某些变体:
if ( a[mid] < x ) # Condition 1:
n = mid; # we set n to mid
else if ( a[mid] > x ) # Condition 2:
i = mid + 1; # we set i to mid+1
else return mid; # Condition 3: we exit loop (let's not worry about this)
所以现在让我们关注mid
,因为我们的while
条件似乎总是根据这个值被削减(因为while
条件取决于i
和n
,其中之一将每次循环迭代后设置为mid
的值):
mid = ( n + i ) / 2; # mid = average of n and i
查看这些函数后,我们可以有效地看到这里发生了什么:
函数将在
i < n
时执行代码,每次循环迭代后i
或n
的值设置为平均值,有效地将i
和n
之间的空间减少了一半每次循环迭代。
这个算法被称为binary search,其背后的想法是我们每次在循环中迭代时都将数组边界减半。
所以你可以把它想象成我们一直把n
切成两半,直到我们不能再切成两半。
定量分析
查看此问题的数学方法是查看我们在每次迭代中有效地将 n
除以 2,直到 i
和 n
彼此相等(或 n < i
)。
所以让我们考虑一下我们可以将 n 除以 2 多少次直到等于 1?在这种情况下,我们希望我们的 n 等于 1,因为那是我们无法进一步拆分列表的时候。
所以我们得到了一个等式,其中x
是我们执行while
循环所需的时间:
n/2^x = 1
n = 2^x
lg(n) = lg(2^x)
lg(n) = x lg(2)
lg(n) = x
如您所见,x = lg(n)
因此我们可以得出结论,您的算法在 O(lgn)
中运行
【讨论】:
以上是关于该算法的复杂度函数的主要内容,如果未能解决你的问题,请参考以下文章