C# 求递归算法空间复杂度的一般方法是什么?
对于这类算法(如斐波那契算法),一般的空间复杂度计算方法是什么?我们需要找到调用堆栈的深度?递归算法所需的空间可以用三个元素来近似表示。存储所需的空间C# 求递归算法空间复杂度的一般方法是什么?,c#,algorithm,big-o,C#,Algorithm,Big O,对于这类算法(如斐波那契算法),一般的空间复杂度计算方法是什么?我们需要找到调用堆栈的深度?递归算法所需的空间可以用三个元素来近似表示。存储所需的空间 递归堆栈 输入函数的参数 函数的输出 在阶乘的例子中。递归公式是T(n)=T(n-1)+c。当展开它时,你会得到T(n)=T(n-1)+T(n-2)+…+n c。所以递归堆栈需要O(n)空间 函数的输出将是n,要存储一个数字n,您需要日志(n)位。因此,要存储结果,您需要log(n!)=O(n logn)space 在递归的每个步骤中,需要存
- 递归堆栈
- 输入函数的参数
- 函数的输出
T(n)=T(n-1)+c
。当展开它时,你会得到T(n)=T(n-1)+T(n-2)+…+n c
。所以递归堆栈需要O(n)
空间
函数的输出将是n
,要存储一个数字n
,您需要日志(n)位。因此,要存储结果,您需要log(n!)=O(n logn)
space
在递归的每个步骤中,需要存储1个参数(n
)。您需要将其存储n
次,每个参数占用log(n)
空间。因此,总的O(nlogn)
所以你最终得到了O(n)+O(nlogn)+O(nlogn)=O(nlogn)
。这是计算阶乘递归所需的空间
通过此分析,您可以找到为什么执行alpa beta修剪的国际象棋程序需要大量ram才能正确计算位置。在以这样的形式编写时间复杂性之后 T(n)=T(n-1)+n 或 T(n)=2T(n/2)+nlogn 等等 您有两个选择: 1) 使用重复替换法,这在某些情况下需要一些数学技能,因为您应该遵循步骤直到T(1)或T(0),然后计算总和 或
2) 使用主定理,它类似于公式,适用于许多实际情况您必须递归调用它n次,每次调用都会在堆栈上分配自己的带有局部变量的帧,因此空间复杂度为n。每次调用
阶乘
函数都会在“堆栈”中创建堆栈帧用于该调用的部分内存。单个堆栈帧将包含此函数中定义的变量、函数中的参数和返回地址。在这种情况下,每次调用都可以在固定时间内存储此信息。因为对这个函数的调用将是线性的,所以总内存将是O(n)。我理解你的解释,但为什么其他人都说空间复杂度是O(n)?@ivan_petrushenko问他们存储一个数字需要多少空间n代码>。让我们选择一个小数字,比如5000。他们会说这是O(1)
?对。对于n
的大值,空间复杂度将不是线性的,时间复杂度(我猜)也是一样的,因为在返回n*factorial(n-1)
中,两个非常大的数字相乘不能被视为常数时间运算。我写了O(n)
,因为我想当然地认为,既然OP使用int
,那么它就不能存储大于19的数字代码>。
int factorial(int n)
{
if(n < 0) {return -1;}
if(n == 0) {return 1;}
return n*factorial(n-1);
}
T(n) = T(n-1) + c = T(n-2) + 2c = ... = T(n-k) + kc => O(n)
T(0) = 1;