再帰関数の複雑さの判定(Big O 表記) 質問する

再帰関数の複雑さの判定(Big O 表記) 質問する

明日はコンピュータ サイエンスの中間試験があり、これらの再帰関数の複雑さを判断するのに助けが必要です。簡単なケースの解決方法はわかっていますが、これらの難しいケースの解決方法をまだ学ぼうとしています。これらは、私が理解できなかった例題のほんの一部です。どんな助けでも大歓迎ですし、勉強に大いに役立ちます。ありがとうございます。

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);
}

ベストアンサー1

各関数の時間計算量(Big O 表記):


int recursiveFun1(int n)
{
    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun1(n-1);
}

この関数は、基本ケースに到達する前に n 回再帰的に呼び出されるため、その は線形O(n)と呼ばれることがよくあります。


int recursiveFun2(int n)
{
    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun2(n-5);
}

この関数は n-5 回呼び出されるので、関数を呼び出す前に n から 5 を減算しますが、n-5 も ですO(n)。(実際には n/5 回順に呼び出されます。そして、O(n/5) = O(n) です)。


int recursiveFun3(int n)
{
    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun3(n/5);
}

この関数は 5 を底とする log(n) です。関数を呼び出す前に毎回 5 で割るため、O(log(n))(底 5) は対数と呼ばれることが多く、ほとんどの場合 Big O 表記法と複雑性分析では底 2 が使用されます。


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);
    }
}

ここでは、各関数呼び出しはn回再帰されない限り、それ自体を 2 回呼び出すため、O(2^n)つまり指数 になります。



int recursiveFun5(int n)
{
    for (i = 0; i < n; i += 2) {
        // do something
    }

    if (n <= 0)
        return 1;
    else
        return 1 + recursiveFun5(n-5);
}

ここで、forループは2ずつ増加しているのでn/2かかり、再帰はn/5かかり、forループは再帰的に呼び出されるので、時間計算量は

(n/5) * (n/2) = n^2/10、

漸近的な動作と最悪のシナリオの考慮、またはビッグ O が目指す上限により、最大の項のみに関心があるため、 となりますO(n^2)


中間試験頑張ってください ;)

おすすめ記事