Algorithm 从第一原理进行复杂性分析的程序

Algorithm 从第一原理进行复杂性分析的程序,algorithm,complexity-theory,Algorithm,Complexity Theory,假设我想在这个简单的循环上执行复杂性分析- for (int i = 0; i < n; i++) { a = i + 1; } for(int i=0;i

假设我想在这个简单的循环上执行复杂性分析-

for (int i = 0; i < n; i++)
{
    a = i + 1;
}
for(int i=0;i
这就是我所做的,这是正确的程序还是我走得太远了

将0初始分配给i:1操作

循环执行n次:

  • i与n的比较:执行n+1次
  • 增量i:执行n次操作
  • 将i+1分配给a:执行了n次两次操作
因此,操作总数:1+(n+1)+n+2n=4n+2 这有很大的Oh(n)复杂性


这是正确的吗?有更好的方法吗?

最终结论是正确的,算法是
O(n)

然而,在分析算法时,我们通常避免精确计算执行了多少次操作,而只查找上界和下界,因为确切的细节可能取决于实现

例如,在您的代码中-可能会减少代码中比较操作的数量,并且您计算的操作的确切数量与实际执行的操作的数量并不完全相同


此外,这假设
a
int
或某个基本类型,并且
操作符=
操作符+
是在固定时间内完成的。例如,如果
a
是某种大整数或类似字符串的运算符,并且您重载了运算符-可能每个
运算符=
都是
O(| a |)
,这使得算法
O(nlogn)
,或
O(n^2)
,(或其他东西),根据
a

类型的具体实现,最终结论是正确的,算法是
O(n)

然而,在分析算法时,我们通常避免精确计算执行了多少次操作,而只查找上界和下界,因为确切的细节可能取决于实现

例如,在您的代码中-可能会减少代码中比较操作的数量,并且您计算的操作的确切数量与实际执行的操作的数量并不完全相同

此外,这假设
a
int
或某个基本类型,并且
操作符=
操作符+
是在固定时间内完成的。例如,如果
a
是某种大整数或类似字符串的运算符,并且您重载了运算符-可能每个
运算符=
都是
O(| a |)
,这使得算法
O(nlogn)
,或
O(n^2)
,(或其他东西),根据
a

类型的具体实现,它是完全正确的。(但注意每个操作都要占用O(1)时间。如果操作是函数调用,则还必须考虑其运行时复杂度

。 下次,您可能会发现一个“关键”操作,并只计算该操作执行的次数。例如,在您的示例中,很明显,对于执行的每个赋值操作,比较和增量操作的次数都是恒定的,因此,如果只计算赋值的次数,就可以了

直接计算操作的执行次数总是很容易的。更困难的情况是,当你不能直接计数,但例如得出一个递归公式,即T(n+1)=a T(n/b)+f(n)等。这是完全正确的。(但注意每个操作都要占用O(1)时间。如果操作是函数调用,则还必须考虑其运行时复杂度

。 下次,您可能会发现一个“关键”操作,并只计算该操作执行的次数。例如,在您的示例中,很明显,对于执行的每个赋值操作,比较和增量操作的次数都是恒定的,因此,如果只计算赋值的次数,就可以了


直接计算操作的执行次数总是很容易的。当你不能直接计数,但得到一个递归公式,例如T(n+1)=a T(n/b)+f(n)等时,会出现更困难的情况。

是的,这是正确的,它也有ω(n)复杂度和θ(n)复杂度。是的,接下来你将了解哪些事情可以忽略(比如在添加多项式时,你只需要最高阶项。)但是思考所有的运算是一个很好的开始。是的,这是正确的,它也有ω(n)复杂度和θ(n)复杂度。是的,接下来你将了解哪些事情可以忽略(比如在添加多项式时,你只需要最高阶项)。但是思考所有的运算是一个很好的开始。