私は明日Computer Science Midtermを持っています、そして私はこれらの再帰的関数の複雑さを決定するのを手伝う必要があります。私は単純なケースを解決する方法を知っていますが、私はまだこれらのより難しいケースを解決する方法を学ぶことを試みています。これらは、私が理解できなかったほんの数例の問題です。どんな助けも大いに感謝され、私の研究に大いに役立つでしょう、ありがとう!
int recursiveFun1(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun1(n-1);
}
int recursiveFun2(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun2(n-5);
}
int recursiveFun3(int n)
{
if (n <= 0)
return 1;
else
return 1 + recursiveFun3(n/5);
}
void recursiveFun4(int n, int m, int o)
{
if (n <= 0)
{
printf("%d, %d\n",m, o);
}
else
{
recursiveFun4(n-1, m+1, o);
recursiveFun4(n-1, m, o+1);
}
}
int recursiveFun5(int n)
{
for (i = 0; i < n; i += 2) {
// do something
}
if (n <= 0)
return 1;
else
return 1 + recursiveFun5(n-5);
}
各関数のBig O表記での時間の複雑さは、番号順になっています。
O(n)
はしばしばlinearと呼ばれます。O(n)
です。 (実際にはn/5の次数と呼ばれる。そして、O(n/5) = O(n))。O(log(n))
(5進数)は、しばしば対数と呼ばれ、ほとんどの場合、Big O表記と複雑度解析はbaseを使用します2。O(2^n)
、または指数です、なぜならそれが再帰されない限り、各関数呼び出しはそれ自身を2回呼び出すからですn回。最後の関数については、forループは2ずつ増えていくのでn/2、再帰はn-5となり、forループは再帰的に呼び出されるので(n-5)*(n/2)=(2n-10)* n = 2n ^ 2-10n、漸近的な振る舞いと最悪のシナリオの考慮事項、または大きなOが求めている上限のために、最大O(n^2)
のみに関心があります。
あなたの中期に頑張ってください;)
再帰的アルゴリズムの複雑さを近似するために私が見つける最良の方法の1つは、再帰木を描くことです。再帰木ができたら:
Complexity = length of tree from root node to leaf node * number of leaf nodes
n
、リーフノードの数は1
なので、複雑さはn*1 = n
になります。2番目の関数の長さはn/5
、リーフノードの数は1
なので、複雑さはn/5 * 1 = n/5
になります。それはn
に近似されるべきです
3番目の関数では、再帰呼び出しごとにn
が5で除算されているため、再帰ツリーの長さはlog(n)(base 5)
、リーフノードの数は1となり、複雑さはlog(n)(base 5) * 1 = log(n)(base 5)
になります。
4番目の関数では、すべてのノードに2つの子ノードがあるため、リーフノードの数は(2^n)
、再帰ツリーの長さはn
になり、複雑さは(2^n) * n
になります。しかし、n
は(2^n)
の前では重要ではないため、無視することができ、複雑さは(2^n)
としか言いようがありません。
5番目の機能については、複雑さを導入する2つの要素があります。関数の再帰的な性質によって導入される複雑さ、および各関数のfor
ループによって導入される複雑さ。上記の計算を行うと、関数の再帰的な性質によってもたらされる複雑さは~ n
とforループによる複雑さn
になります。全体の複雑さはn*n
になります。
注:これは複雑さを計算するための迅速で汚い方法です(公式なことは何もしていません!)これについてのフィードバックを聞きたいです。ありがとう。