filter再帰呼び出しがnありますが、各反復でコピー操作も行うnため、最終的に Θ(n^2) になります。ただし、「適切に」実装した場合は、 Θ(n) になるはずです。
についても同じですmy_reverse。
についても同じですrevfilter_beta。
revfilter_alphafiltera を実行してからa を実行するだけなreverseので、 Θ(n^2 + n^2) = Θ(n^2) になります。
filter編集:もう少し調べてみましょう。
把握したいのは、入力のサイズに対して実行される操作の数です。O(n)最悪の場合、n操作の順序で行うことを意味します。たとえば、O(n/2)操作を行うことができるため、「の順序で」と言いますO(4n)が、最も重要な要素はnです。つまり、 がn成長するにつれて、一定の要因はますます重要性が低くなるため、非一定の要因 (nこの場合) のみを調べます。
filterでは、 size のリストに対していくつの操作が実行されるnでしょうか?
下から見ていきましょう。n0 - 空のリストの場合はどうなりますか? その後、空のリストが返されます。これが 1 つの操作であるとしましょう。
1の場合nは?含める必要があるかどうかlst[0]をチェックします - そのチェックは呼び出すのに時間がかかりますf- そしてリストの残りをコピーし、そのコピーに対して再帰呼び出しを行います。この場合は空のリストです。操作はsofilter(1)かかり、はリストをコピーするのにかかる時間であり、は要素を含める必要があるかどうかを確認するのにかかる時間です。ただし、各要素に同じ時間がかかると仮定します。f + copy(0) + filter(0)copy(n)f
どうfilter(2)ですか?1 つのチェックを実行してから、リストの残りをコピーし、残りを呼び出しfilterますf + copy(1) + filter(1)。
その模様はすでにご覧いただけます。filter(n)かかります1 + copy(n-1) + filter(n-1)。
今、copy(n)ちょうどですn-nそのようにリストをスライスするには操作が必要です。したがって、さらに単純化できますfilter(n) = f + n-1 + filter(n-1)。
これで、何回か展開してfilter(n-1)何が起こるかを確認できます。
filter(n) = f + n-1 + filter(n-1)
= 1 + n-1 + (f + n-2 + filter(n-2))
= f + n-1 + f + n-2 + filter(n-2)
= 2f + 2n-3 + filter(n-2)
= 2f + 2n-3 + (f + n-3 + filter(n-3))
= 3f + 3n-6 + filter(n-3)
= 3f + 3n-6 + (f + n-4 + filter(n-4))
= 4f + 4n-10 + filter(n-4)
= 5f + 5n-15 + filter(n-5)
...
x繰り返しを一般化できますか? その1, 3, 6, 10, 15... シーケンスは三角形の数字です。つまり1、 、1+2、1+2+3、などです。 からまで1+2+3+4のすべての数字の合計は です。1xx*(x-1)/2
= x*f + x*n - x*(x-1)/2 + filter(n-x)
さて、何xですか?何回繰り返しますか?x=の場合、再帰 - = =nがなくなることがわかります。したがって、式は次のようになります。filter(n-n)filter(0)1
filter(n) = n*f + n*n - n*(n-1)/2 + 1
さらに単純化できます。
filter(n) = n*f + n^2 - (n^2 - n)/2 + 1
= n*f + n^2 - n^2/2 + n/2 + 1
= n^2 - n^2/2 + f*n + n/2 + 1
= (1/2)n^2 + (f + 1/2)n + 1
これで、かなり詳細な分析ができました。それは...が取るに足らない(たとえば= 1)とΘ((1/2)n^2 + (f + 1/2)n + 1)仮定すると、 になります。ffΘ((1/2)n^2 + (3/2)n + 1)
copy(n)ここで、直線的な時間ではなく一定の時間がかかった場合 (copy(n)が ではなく 1 の場合n)、そのn^2用語はそこに含まれないことに気付くでしょう。
私がΘ(n^2)最初に言ったとき、私はこれをすべて頭の中でやったわけではないことを認めます. むしろ、私は次のように考えました:わかりました、n再帰的なステップがnあり、copy. n*n = n^2、したがってΘ(n^2)。それをもう少し正確に行うには、n各ステップで縮小するため、実際にはn + (n-1) + (n-2) + (n-3) + ... + 1、上記と同じ図n*n - (1 + 2 + 3 + ... + n)= n*n - n*(n-1)/2=になります。これは、上記の の代わりに(1/2)n^2 + (1/2)n使用した場合と同じです。同様に、ステップがあり、各ステップが代わりに実行された場合 (リストをコピーする必要がなかった場合)、、時間、または単に.0fn1n1 + 1 + 1 + ... + 1nn
しかし、それにはもう少し直感が必要なので、何にでも適用できる力ずくの方法もお見せしたいと思います。