Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 求递归算法空间复杂度的一般方法是什么?_C#_Algorithm_Big O - Fatal编程技术网

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;