web-dev-qa-db-ja.com

再帰的メソッドのビッグO

単純な再帰メソッドの大きなOを決定するのに苦労しています。メソッドが複数回呼び出されたときに何が起こるかについて頭を悩ませることはできません。私は自分の混乱している分野についてより具体的に説明しますが、現時点ではいくつかのハードウェアの質問に答えようとしています。不正行為をしたくないのではなく、この投稿に回答する人は誰でも簡単な再帰的な方法を考えてください。上記の方法の大きなOの簡単な説明を提供します。 (できればJavaで...私が学んでいる言語です。)

ありがとうございました。

18
user1333461

順序を再帰的に定義することもできます。たとえば、関数fがあるとします。 f(n)を計算するにはkステップかかります。次にf(n + 1)を計算します。f(n + 1)がf(n)一度、f(n + 1)はk +いくつかの一定のステップを取ります。各呼び出しはいくつかの一定のステップを余分に取るので、このメソッドはO(n)です。

次に、別の例を見てください。前の2つの結果を追加して、フィボナッチを素朴に実装するとします。

fib(n) = { return fib(n-1) + fib(n-2) }

ここで、fib(n-2)とfib(n-1)の両方を約kステップで計算できるとしましょう。 fib(n)を計算するには、k + k = 2 * kステップが必要です。ここで、fib(n + 1)を計算するとします。したがって、fib(n-1)の2倍のステップが必要です。だからこれはO(2 ^ N)のようです

確かに、これはあまり正式ではありませんが、うまくいけば、この方法で少し感じを得ることができます。

32
markijbema

再帰的メソッドの大きなOを見つけるには、マスター定理を参照することをお勧めします。ウィキペディアの記事は次のとおりです。 http://en.wikipedia.org/wiki/Master_theorem

あなたは木のような再帰的な問題を考えたいと思います。次に、ツリーの各レベルと必要な作業量を検討します。問題は一般に、ルートヘビー(最初の反復>>ツリーの残り)、バランス(各レベルの作業量が等しい)、リーフヘビー(最後の反復>>ツリーの残り)の3つのカテゴリに分類されます。

例としてマージソートを取り上げます。

define mergeSort(list toSort):
    if(length of toSort <= 1):
        return toSort
    list left = toSort from [0, length of toSort/2)
    list right = toSort from [length of toSort/2, length of toSort)
    merge(mergeSort(left), mergeSort(right))

MergeSortを呼び出すたびに、元の長さの1/2のmergeSortsがさらに2つ呼び出されることがわかります。マージ手順には、マージされる値の数に比例して時間がかかることがわかっています。

その場合、漸化式はT(n) = 2 * T(n/2)+ O(n)です。2つは2つの呼び出しからのもので、n/2は次の各呼び出しからのものです。要素の数は半分にすぎません。ただし、各レベルには、マージする必要のある要素の数nが同じであるため、各レベルでの一定の作業はO(n)です。

作業が均等に分散され(各深さO(n))、ツリーの深さがlog_2(n)であることがわかっているため、再帰関数の大きなOはO(n * log(n))です。

15
Calvin Jia