複雑性分析
すなわち、より速く安くストレージスペースをあなたのコードの実行を作るためにどのような問題そのものを解決するために、データ構造とアルゴリズム、「高速」と「省」、。したがって、このアルゴリズムの効率は非常に重要な考慮事項指標です。コードは、あなたがそれを書くことを、アルゴリズムの効率を測定するには?そして、あなたは、分析の複雑さを使用する必要があり、それは「時間計算量に分割して解析」と「宇宙の複雑さの解析」リアルタイム実行のための特定のコードを示すものではありませんが、説明のコードの実行時間(またはスペース)のデータとトレンドスケールの成長。
ランダウの記号
すべてのコードが実行される時間T(n)はn個のコードの各ラインの周波数に比例します。私たちは式には、この法律をまとめることができます。
T(N)= O(F(N))
ここで、T(n)は、スクリプトの性能を表し、n-表すデータサイズの大きさを、F(n)が実行されるコードの各行の数の合計を表します。これは式であるため、そうF(N)と表されます。O、実行時間コードT(n)とF(N)からの式は、式に比例します。
この表記によれば、コードビュー。
1 INT CAL(int型N){ 2 INTの和= 0 。 3 INT iが1を= 。 4 のための(; I <= N; ++ I){ 5 和=和+ I。 6 } 7 戻り和。 8 }
2行目と3行目4、5、行操作をn回にわたり必要とされ、時間2Nを行う必要がある* O、このコードの総実行時間(2N + 2)* O. これは、T(N)= O(2N + 2)、見ることができます。
コードの別の部分を見てください
1 INT CAL(int型N){ 2 INTの和= 0 。 3 INT iが1を= 。 4 int型の J = 1 。 5 のための(; I <= N; ++ I){ 6 J = 1 。 7 のための(; J <= N; ++ J){ 8 和= I * +和J。 9 } 10 } 11 }
2,3,4行ごとに必要なコードの行行うようにパスを、5,6-線ループが実行されたn回、2Nに必要な実行時間* O、7および8線ループが実行されたN2回それは2N必要と2 * Oの実行時間を。したがって、コードの総実行時間Tの全セクション(N)=(2N 2 + 2N + 3)* O.
ときに大きなN、あなたは10000,100000と考えることができます。下位の3部構成式は、一定の係数は成長傾向に関するものではありません、それは無視することができます。その上に記録された唯一最大の大きさ、2つの符号その上の時間複雑さは、それはのように書くことができる:T(N)= O(N)、T(N)= O(N 2)。
時間の複雑さの解析
4つの方法は、より実用的かもしれ存在するコードの複雑さの一片分析時間:
1 )のみコードの一部を実行サイクルの最も数に関係
そのようなコードの上記第一部品として、2行目と3行目は関係なく、nの大きさ、全く効果のための複雑さの、定数ステージの実行時間です。ループはこのキーコードを解析するようにコードの行の最大数は、4,5であり実行する、全体的な時間計算量はO(N)です。
2)最大ルール:のコードの大部分の大きさに等しい全体的な複雑さの複雑さ
そのようなコードの一部として単一サイクルおよび複数のサイクル、その後、複数のサイクルを取ることの複雑さを有します。
1つの int型の CAL(INT N){ 2 INT sum_1 = 0 。 3 INT P = 1 。 4 のための(; P <100; ++ P){ 5 sum_1 = sum_1 + P。 6 } 7 8 INT sum_2 = 0 。 9 INT Q = 1 。 10 のために(; Q <N; ++ Q){ 11 sum_2 = sum_2 + Q。 12 } 13 14 INT sum_3 = 0 。 15 のint i = 1から; 16 のint J = 1 。 17 のために(; I <= N; ++ I){ 18 J = 1 。 19 のために(; J <= N; ++ j)は{ 20 sum_3 = sum_3 + I * J。 21 } 22 } 23 24 リターン sum_1 + sum_2 + sum_3。 25 }
コードはsum_1、sum_2、sum_3を求め、つまり、3つの部分に分割されます。私たちは、個別に各パートの時間複雑さを分析して、それらを一緒に入れ、その後、全体のコードの最大複雑さと大きさの注文を取ることができます。
3部構成のコードの複雑さは、O(1) O(N)とO(N 2)。コードの3つのセクション全体の時間の複雑さは、我々は大きさの最大を取ります。したがって、コード全体の時間複雑度は、O(N 2)です。言い換えれば、総時間の複雑さは、コードの大部分のための時間計算量と同等です。
3)乗算ルール:ネストされたタグの複雑さは、ネストされた内側及び外側コードの複雑さの積に等しいです。
例えば、再帰的な、マルチサイクル、等
4)加算器の複数のスケール
この方法は、例えば、周波数2つの制御周期、などの2つのパラメータの複雑さを追加する方の時間を有しています。
1つの int型の CAL(INT M、INT N){ 2 INT sum_1 = 0 。 3 INT iが1を= 。 4 のための(; I <M; ++ I){ 5 sum_1 = sum_1 + I。 6 } 7 8 INT sum_2 = 0 。 9 INTの J = 1 。 10 のために(、J <N; ++ j)は{ 11 sum_2 = sum_2 + J。 12 } 13 14 リターン sum_1 + sum_2。 15 }
コード、Mから見てNすることができるように、2つのデータサイズを表します。私たちは、事前にその巨大なので、我々は複雑さを表し、単に追加ルール、省略されているのいずれかを使用することはできませんm程度とnを評価することはできません。したがって、上記タイムコードはO(M + N)の複雑さです。
時間複雑分析の一般的な例
1.(1)
O(1)だけでなく、唯一のレベル表現一定時間の複雑なコードの行を指すが実行されます。このコード例では、3行があっても、その時間複雑度はO(1)の代わりに、O(3)です。
1 INT iが8 = 。 2 INTの J = 6 。 3 int型の合計= I + J;
限り、コードの実行時間は、我々はO(1)と呼ばているので、コードの時間複雑こと、Nの増加に伴って増加しません。あるいは、通常の状況下で、限りループとして、再帰アルゴリズム文は何千行ものコードがある場合でも、存在しない、時間複雑度はΟ(1)です。
2.(LOGN)、(nlogn)
1 I 1 = 。 2 一方、(I <= N){ 3 私* 2 = 。 4 }
可変のコード値から分かるように、サイクル毎に2つを乗じた後、私は、最初から取られます。場合nより大きい、ループを終了します。実際には、変数iの値は等比数列です。
2 22 23 24 ... 2x = n
所以,只要知道 x 值是多少,就知道这行代码执行的次数了。x=log2n,所以,这段代码的时间复杂度就是 O(log2n)。实际上,不管是以 2 为底、以 3 为底,还是以 10 为底,在对数阶时间复杂度的表示方法里,我们忽略对数的“底”,统一表示为 O(logn)。
理解 O(logn),那 O(nlogn) 就很容易理解了。如果一段代码的时间复杂度是 O(logn),我们循环执行 n 遍,时间复杂度就是 O(nlogn) 了。而且,O(nlogn) 也是一种非常常见的算法时间复杂度。比如,归并排序、快速排序的时间复杂度都是 O(nlogn)。
3. O(m+n)、O(m*n)
代码的复杂度由两个数据的规模来决定。代码同时间复杂度分析的“4)”
空间复杂度分析
时间复杂度的全称是渐进时间复杂度,表示算法的执行时间与数据规模之间的增长关系。类比一下,空间复杂度全称就是渐进空间复杂度(asymptotic space complexity),表示算法的存储空间与数据规模之间的增长关系。
1 void print(int n) { 2 int i = 0; 3 int[] a = new int[n]; 4 for (i; i <n; ++i) { 5 a[i] = i * i; 6 } 7 8 for (i = n-1; i >= 0; --i) { 9 print out a[i] 10 } 11 }
跟时间复杂度分析一样,第 2 行代码中,申请了一个空间存储变量 i,但是它是常量阶的,跟数据规模 n 没有关系,所以可以忽略。第 3 行申请了一个大小为 n 的 int 类型数组,除此之外,剩下的代码都没有占用更多的空间,所以整段代码的空间复杂度就是 O(n)。
常见的空间复杂度就是 O(1)、O(n)、O(n2),像 O(logn)、O(nlogn) 这样的对数阶复杂度平时都用不到。而且,空间复杂度分析比时间复杂度分析要简单很多。所以,对于空间复杂度,掌握这些内容已经足够了。