図1は、アルゴリズム:アルゴリズムは、特定の問題解決のステップを解決する記述は、コンピュータ内の命令の有限のシーケンスとして表され、各々は、一つ以上の命令の動作を表します。
だから、アルゴリズムの種類は、アルゴリズムの品質を判断するために何の基準が存在しないことを意味良いアルゴリズム、呼び出すことができますか?
これに先立ち、まずはテストを受けてみましょう:
シーク達成する二つの方法ペイフィボナッチ数列の再帰的モードの最初のn項の値を、通常の周期的と第二のモード。
前の結果を得るために、あなたはその方法がより速く結果を推測する、または早く?
テストコード(JavaScriptの)次のように
/ * * * 1、再帰フィボナッチ数が記載されている: * = 1,1,2,3,5 ... N最初のアイテムのアイテムのn-1 + N-2-項目 * * / 機能recursionFbi(N) { IF(N- <3)リターン。1 ; IF(N - == 3)リターン 2 ; // はconsole.log( "再帰N-"、N-); 戻り recursionFbiをrecursionFbi +(2-N-(1-N-)); } / * * * 2、サイクル実現ペイフィボナッチ数列 * = 1,1,2,3,5 ... N最初のアイテムのアイテムのn-1 + N-2-項目 * * / 機能circleFbi(N) { IF(N- <3)リターン 1。; VARの A = 1、B = 1の、C = 0。; 用(VAR i = 0; iは<N; iは++ ){ 場合(I> 1 ){ C = A + B。= B; B =のCと、 } はconsole.log( "循环I:"、I、 "C:" 、C)。 } 戻りC。 }
図は、ここで入力されたいくつかのテストが、結果は、実質的に比較のために記録されています。
もちろん、各試験はと一定の関係を開くために、現在のテストコンピュータのハードウェア構成、および他のアプリケーションと、数は必ずしも同じではない、同じ時間を算出します。
入力はn = 51、次の試験結果は、スクリーンショット。
その他の統計n個の入力値の数があります。
驚くほどの時間差の値の喪失によって実証され、2つの方法で、上記の要件ペイフィボナッチ数列、!なぜこのような大きな違いがありますか?これは、プログラムをより効果的にするための良いアルゴリズムの動作効率を反映して、プログラムに悪いアルゴリズムは、単に災害です!それからちょうどアルゴリズムのこれら二つの方法の違い、そして次の分析を待ちます。
2は、今、私たちのためにどのように良いまたはアルゴリズムの概算悪いと言っています。
:ある私たちは、アルゴリズムの要件を設計精度、読みやすさ、堅牢性、高い時間効率、低ストレージ容量。
我々は実行する前に、このようなアルゴリズムのために、それは5つの角度の分析から決定することができる、とビューの時間効率の点から主記憶装置には、次のことを詳しく説明します。
- 時間の複雑さ(時間計算):実行プログラム命令数の推定値(実行時間)
- 制御の複雑さ(スペース複雑さ):占有必要なストレージ容量を見積もります
ランダウの記号は、我々は、アルゴリズムの時間の複雑さを記述するためにそれを使用し、迅速なアルゴリズムの効率を推定するために私たちを助けることができ、大まかなモデルです。
これらの共通の時間の複雑さ:
最高次の項の一定の除去;のみ最高次の項を残し、複数次項;大O導出方法は、一定の順序のために、我々は、一定の1で置き換えられたとき。図:
このペーストのいくつかの例は練習時間(JavaScriptの)の複雑さを計算するのに使用されます。
//算法复杂度:O(n) function testCount1(n){ //指令计数:多个if算作一个指令 if (n > 10){ console.log("n > 10") } else if(n > 5){ console.log("n > 5") } else{ console.log("n <= 5") } //指令计数:1 + n + n + n = 3n + 1 for (var i = 0; i < n; i++){ console.log("...testCount1...") } } //算法复杂度:O(logn) function testCount3(n){ //指令计数:n/2 = log2(n) //n=2 -> 1; n=4->2; n = 8->3; n = 16->4; n = 32->6 //1=log2(2); 2=log2(4); 3=log2(8); 4=log2(16); 6=log2(32) while((n = n / 2) > 0){ console.log("***testCount3***"); } } //算法复杂度:O(nlogn) function testCount4(n){ //指令计数:1 + 2*log2(n) + log2(n) * (1+3n) = 1 + 3log2(n) + 3n*log2(n) for (var i = 1; i < n; i = i * 2){ //1 + 3n for (var j = 0; j < n; j++){ console.log(">>>testCount4>>>") } } } //算法复杂度:O(n^2) function testCount2(n){ //指令计数:1 + 2n + n * (1+3n) = 1 + 3n + 3n^2 = 3n^2 + 3n + 1 for (var i = 0; i < n; i++){ for (var j = 0; j < n; j++){ console.log("...testCount2...") } } }
常见的时间复杂度所耗时间的大小排列如下:
3、掌握了大O推导法,我们用大O表示法来论证本文最开始计算裴波那契数列的两种算法的区别:
3.1 递归方式算法,先看下图:
可以得出,这里的递归方式算法用大O表示法来表示,它属于指数阶,可以粗略表示为:O(n) = 2^n
3.2 而第二种循环方式算法为线性阶的,用大O表示法为:O(n) = n
3.3 我们对比一下指数阶和线性阶的函数曲线图就知道,n系数越大,这两种方式的最后的结果相差越大。
所以当n越大时,递归方式算法的计算次数呈指数级上升,最后次数结果越大,时间损耗数也就越多。