-------------------------------------資源來源於網絡,僅供自學使用,如有侵權,聯繫我必刪.
第一:
算法效率的度量
? 事前分析估算
依據統計的方法對算法效率進行估算
? 影響算法效率的主要因素
算法採用的策略和方法
問題的輸入規模
編譯器所產生的代碼
計算機執行速度
第二:
算法效率的簡單估算
二重循環估算
#include <stdio.h>
//(n*n + 4)T
int func(int a[], int len)
{
// 3次
int i = 0;
int j = 0;
int s = 0;
//n*n
for(i=0; i<len; i++)
{
for(j=0; j<len; j++)
{
s += i*j;
}
}
//1
return s;
}
int main()
{
int array[] = {1, 2, 3, 4, 5};
//估算func函數的操作數量
printf("%d\n", func(array, 5));
return 0;
}
? 啓示
上面的程序關鍵部分的操作數量爲n*n
隨着問題規模n 的增大 , 它們操作數量的差異會越來越大 , 因此實際算法在時間效率上的差異也會變得非常明顯 !
第三:
時間複雜度:
? 大O 表示法
算法效率嚴重依賴於操作(Operation) 數量
在判斷時首先關注操作數量的最高次項
操作數量的估算可以作爲時間複雜度的估算
O(5) = O(1)
O(2n + 1) = O(2n) = O(n)
O(n 2 + n + 1) = O(n 2 )
O(3n 3 +1) = O(3n 3 ) = O(n 3 )
時間複雜度:
#include <stdio.h>
int search(int array[], int length, int n)
{
int ret = -1;
int i = 0;
for(i=0; i<length; i++)
{
if( array[i] == n )
{
ret = i;
break;
}
}
return ret;
}
int main()
{
int array[5] = {1, 2, 3, 4, 5};
printf("%d\n", search(array, 5, 1)); //最好情況執行1次,複雜度o(1)
printf("%d\n", search(array, 5, 5)); //最壞情況執行n次,複雜度o(n)
return 0;
}
在沒有特殊說明時,我們所分析的算法的時間複雜度都是指最壞時間複雜度
第四:
算法的空間複雜度
? 算法的空間複雜度通過計算算法的存儲空間實現
S(n ) = O(f(n ))
其中 ,n 爲問題規模 , f(n) 爲在問題規模爲n 時所佔用存儲空間的函數
大O 表示法同樣適用於算法的空間複雜度
當算法執行時所需要的空間是常數時 , 空間複雜度爲 O(1)
空間複雜度估算
#include <stdio.h>
#include <malloc.h>
//4*n+12 byte
long sum1(int n)
{
long ret = 0; //4 byte
int* array = (int*)malloc(n * sizeof(int)); //指針4 + 堆空間n*4
int i = 0; //4
for(i=0; i<n; i++)
{
array[i] = i + 1;
}
for(i=0; i<n; i++)
{
ret += array[i];
}
free(array);
return ret;
}
//8 byte
long sum2(int n)
{
long ret = 0; //4 byte
int i = 0; //4
for(i=1; i<=n; i++)
{
ret += i;
}
return ret;
}
//4 byte
long sum3(int n)
{
long ret = 0; //4 byte
if( n > 0 )
{
ret = (1 + n) * n / 2;
}
return ret;
}
int main()
{
printf("%d\n", sum1(100));
printf("%d\n", sum2(100));
printf("%d\n", sum3(100));
return 0;
}
三種求和算法中求和的關鍵部分的操作數量分別爲2n, n 和1
時間複雜度分別爲o(n),o(n)和o(1)
空間複雜度分別爲o(n),o(1)和o(1)
第五:
空間與時間的策略
? 多數情況下 , 算法執行時所用的時間更令人關注
? 如果有必要 , 可以通過增加空間複雜度來降低時間複雜度
? 同理 , 也可以通過增加時間複雜度來降低空間複雜度
在實現算法時
需要分析具體問題對執行時間和空間的要求
空間換時間
#include <stdio.h>
/*
問題:
在一個由自然數1-1000中某些數字所組成的數組中,每個數字可能出現零次或者多次。
設計一個算法,找出出現次數最多的數字。
*/
//時間複雜度O(n)
void search(int a[], int len)
{
//3
int sp[1000] = {0};
int i = 0;
int max = 0;
//遍歷a[]數組,如果裏面是1則sp[]對應的第一位(sp[0])就加1
for(i=0; i<len; i++) //n
{
int index = a[i] - 1;
sp[index]++;
}
//遍歷數組sp[] 找到最大值
for(i=0; i<1000; i++) //1000
{
if( max < sp[i] )
{
max = sp[i];
}
}
//打印滿足最大值的數
for(i=0; i<1000; i++) //1000
{
if( max == sp[i] )
{
printf("%d\n", i+1);
}
}
}
int main()
{
int array[] = {1, 1, 3, 4, 5, 6, 6, 6, 2, 3};
search(array, sizeof(array)/sizeof(*array));
return 0;
}