——————–我是分割線—————–
時間複雜度:
時間複雜度實際就是乙個函式,該函式計算的是執行基本操作的次
數。 演算法分析的分類:演算法存在最好、平均和最壞情況。
最壞情況:任意輸入規模的最大執行次數(上界)
平均情況:任意輸入規模的期望執行次數
最好情況:任意輸入規模的最小執行次數,通常最好情況不會出現(下界)
例如:在乙個長度為n的線性表中搜尋乙個資料x
最好情況:1次比較
最壞情況:n次比較
平均情況:n/2次比較
在實際中通常關注的是演算法的最壞運**況,即:任意輸入規模n,演算法
的最長執行時間。理由如下:乙個演算法的最壞情況的執行時間是在任意輸入下的執行時間上界,對於某些演算法,最壞的情況出現的較為頻繁,大體上看,平均情況與最壞情況一樣差。因此:一般情況下使用o漸進表示法來計算演算法的時間複雜度。
時間複雜度之大o漸進表示法:
乙個演算法語句總的執行次數是關於問題規模n的某個函式,記為f(n),n
稱為問題的規模。語句總的執行次數記為t(n),當n不斷變化時,t(n)也
在變化,演算法執行次數的增長速率和f(n)的增長速率相同。則有t(n) =
o(f(n)),稱o(f(n))為時間複雜度的o漸進表示法。
一般演算法o(n)計算方法:
(1)用常數1取代執行時間中的所有加法常數
(2)在修改後的執行次數函式中,只保留最高端項
(3)如果最高端項係數存在且不是1,則去除與這個項相乘的常數
空間複雜度:
空間複雜度是對乙個演算法在執行過程中臨時占用儲存空間大小的量度,記做s(n)=o(f(n))。比如菲波那切數列的非遞迴演算法的時間複雜度是o(n),空間複雜度是o(1) 。而一般的遞迴演算法就要有o(n)的空間複雜度了,因為每次遞迴都要儲存返回資訊。乙個演算法的優劣主要從演算法的執行時間和所需要占用的儲存空間兩個方面衡量。
1:實現二分查詢演算法的遞迴及非遞迴。(分析時間複雜度及空間複雜度)
//二分查詢非遞迴
int binarry_search(int arr, int len, int key)
else
if (key>arr[mid])
else
}return -1;
}//時間複雜度 o(lgn)
//空間複雜度 o(1)
//遞迴二分查詢
int recur_binarry_search(int arr, int left, int right, int key)
else
return -1;
}//遞迴二分查詢時間複雜度 o(lgn)
//空間複雜度 o(lgn)
int main();
int len = sizeof(arr) / sizeof(int)-1;
printf("%d\n", recur_binarry_search(arr, 0, len, 0));
printf("%d\n", recur_binarry_search(arr, 0, len, 1));
printf("%d\n", recur_binarry_search(arr, 0, len, 2));
printf("%d\n", recur_binarry_search(arr, 0, len, 3));
printf("%d\n", recur_binarry_search(arr, 0, len, 4));
printf("%d\n", recur_binarry_search(arr, 0, len, 5));
printf("%d\n", recur_binarry_search(arr, 0, len, 6));
printf("%d\n", recur_binarry_search(arr, 0, len, 7));
printf("%d\n", recur_binarry_search(arr, 0, len, 8));
printf("%d\n", recur_binarry_search(arr, 0, len, 9));
printf("%d\n", recur_binarry_search(arr, 0, len, 10));
system("pause");
return
0;}
2:實現斐波那契數列的遞迴及非遞迴。(分析時間複雜度及空間複雜度)
// 非遞迴
int fib1(int n)
while (n-->1)
return b;
}//時間複雜度為 o(n)
//空間複雜度為 o(1)
//遞迴
int fib2(int n)
//時間複雜度 o(2^n)
//空間複雜度 o(n)
int main()
定義:
如果乙個函式中所有遞迴形式的呼叫都出現在函式的末尾,我們稱這個遞迴函式是尾遞迴的。當遞迴呼叫是整個函式體中最後執行的語句且它的返回值不屬於表示式的一部分時,這個遞迴呼叫就是尾遞迴。尾遞迴函式的特點是在回歸過程中不用做任何操作,這個特性很重要,因為大多數現代的編譯器會利用這種特點自動生成優化的**。
原理:
當編譯器檢測到乙個函式呼叫是尾遞迴的時候,它就覆蓋當前的活動記錄而不是在棧中去建立乙個新的。編譯器可以做到這點,因為遞迴呼叫是當前活躍期內最後一條待執行的語句,於是當這個呼叫返回時棧幀中並沒有其他事情可做,因此也就沒有儲存棧幀的必要了。通過覆蓋當前的棧幀而不是在其之上重新新增乙個,這樣所使用的棧空間就大大縮減了,這使得實際的執行效率會變得更高。
例項:
1:實現斐波那契數列的尾遞迴
//尾遞迴
// 112
35813
2134
...int fib3(int n, int a, int b)
else
}//時間複雜度為 o(n)
//空間複雜度為 s(1)
演算法複雜度 時間複雜度和空間複雜度
1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時間多,哪個演算法花費的時間少就可以了。並且乙個演算法花費的時間與演算法中語句的執行次數成正比例,哪個演算法中語句執行次數...
演算法複雜度 時間複雜度和空間複雜度
演算法複雜度 時間複雜度和空間複雜度 關鍵字 演算法複雜度 時間複雜度 空間複雜度 1 時間複雜度 1 時間頻度 乙個演算法執行所耗費的時間,從理論上是不能算出來的,必須上機執行測試才能知道。但我們不可能也沒有必要對每個演算法都上機測試,只需知道哪個演算法花費的時 間多,哪個演算法花費的時間少就可以...
演算法複雜度 時間複雜度和空間複雜度
演算法的時間複雜度是指執行演算法所需要的計算工作量。n稱為問題的規模,當n不斷變化時,時間頻度t n 也會不斷變化。但有時我們想知道它變化時呈現什麼規律。為此,我們引入時間複雜度概念。一般情況下,演算法中基本操作重複執行的次數是問題規模n的某個函式,用t n 表示,若有某個輔助函式f n 存在乙個正...