總結:演算法的時間複雜度換和空間複雜度
一,演算法的時間複雜度
演算法的時間複雜度反應了程式執行時間隨輸入的規模增長而增長的量級,在很大程度上反映出演算法的優劣與否
1,時間複雜度
時間頻度:一個演算法中語句執行的次數稱為語句頻度或者時間頻度記為T(n)
時間複雜度:在剛才提到的時間頻度中,n稱為問題的規模,當n不斷變化的時間,時間頻度T(n) 也會不斷地變化,但有時候我們想知道它變化時呈現什麼規律,為此引入時間複雜度的概念
一般情況下,演算法中的基本操作重複的次數是問題規模n的某個函式,用T(n)表示,若有某個輔助函式f(n),使得當n趨近於無窮大的時候,T(n)/f(n)的極限值為不等於0的常數,則稱F(n)
T(n)=O(f(n))表示存在一個常數C,使得當n趨於正無窮的時候總有T(n) < C*f(n),簡單來說,就是T(n)在趨於正無窮的時最大也就跟f(n)差不對大,也就是說當n趨於正無窮的時候T(n)的上屆是C*f(n)。
常見的是時間複雜度:常數介O(1),對數階O(log2n),線性階O(n),線性對數階O(nlog2n),平方階O(n2),立方階O(n3),......, k次方階O(nk),指數階O(2n)。隨著問題規模的不斷增大,上述時間複雜度不斷地增大,執行效率不斷降低
常見的演算法時間複雜度由小到大依次為:Ο(1)<Ο(log2n)<Ο(n)<Ο(nlog2n)<Ο(n2)<Ο(n3)<…<Ο(2n)<Ο(n!)
2,求解演算法時間複雜度的具體步驟:
(1)找出演算法中的基本語句(演算法中執行最多的那條語句是基本語句,通常是最內層迴圈的迴圈體)
(2)計算基本語句的執行次數和量級(只需要保證基本語句執行次數的數量級,這意味著只要保證基本語句執行次數的函式的最高次冪正確即可,可以忽略所有最低次冪和最高次冪的係數,簡化演算法分析,主要集中在增長率上)
(3)用大O表示演算法的時間效能(將基本語句執行次數的數量級放入大O中)
如果演算法中包含巢狀的迴圈,則基本語句通常是內層巢狀的迴圈體,如果演算法中包含並列的迴圈,則將並列迴圈的時間複雜度相加:
for (i=1; i<=n; i++)
x++;
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
x++;
第一個for迴圈的時間複雜度為Ο(n),第二個for迴圈的時間複雜度為Ο(n2),則整個演算法的時間複雜度為Ο(n+n2)=Ο(n2)
Ο(1)表示基本語句的執行次數是一個常數,一般來說,只要演算法中不存在迴圈語句,其時間複雜度就是Ο(1)
其中Ο(log2n)、Ο(n)、 Ο(nlog2n)、Ο(n2)和Ο(n3)稱為多項式時間,而Ο(2n)和Ο(n!)稱為指數時間。
3,常見時間複雜度示例說明:
(1)O(1)
$a = $b; $b = $c; $c = $a;
以上三條單據頻度都是1,該程式段的執行時間是一個與問題規模n無關的常數,演算法的時間複雜度Wie常數階,記做T(n)=O(1)
演算法的執行時間不隨問題規模n增長而增長,即使演算法中有n條語句,其執行時間也不過是一個較大的常數該類演算法時間複雜度是O(1)。
(2)O(n2)
$num = 0;
for ($i=0; $i < $n; $i++) {
for ($i=0; $i < $n; $i++) {
$num++;
}
}
(3)O(n)
$a = 0;
$b = 1;
for ($i=1;$i<=n;$i++)
{
$s = $a + $b;
$b = $a;
$a = $s;
}
(4)O(log2n)
$i = 1;
while ($i <= $n)
$i = $i * 2;
語句1的頻度是1, 設語句2的頻度是f(n), 則:2^f(n)<=n;f(n)<=log2n 取最大值f(n)=log2n T(n)=O(log2n )
(5)O(n3)
for($i=0;$i<$n;$i++)
{
for($j=0;$j<$i;$j++)
{
for($k=0;$k<$j;$k++)
$x=$x+2;
}
}
4,常用演算法的時間複雜度和空間複雜度
排序法 | 平均時間 | 最差情形 | 穩定度 | 額外空間 | 備註 |
冒泡 | O(n²) | O(n²) | 穩定 | O(1) | n小時較好 |
交換 | O(n²) | O(n²) | 不穩定 | O(1) | n小時較好 |
選擇 | O(n²) | O(n²) | 不穩定 | O(1) | n小時較好 |
插入 | O(n²) | O(n²) | 穩定 | O(1) | 大部分已排序時候好 |
基數 | O(logRB) | O(logRB) | 穩定 | O(n) | B是真數(0-9)R是基數(個十百) |
Shell | O(nlogn) | O(Nⁿ)1<n<2 | 不穩定 | O(1) | s是所選分組 |
快速 | O(nlogn) | O(n2) | 不穩定 | O(nlogn) | n大時較好 |
歸併 | O(nlogn) | O(nlogn) | 穩定 | O(1) | n大時較好 |
堆 | O(nlogn) | O(nlogn) | 不穩定 | O(1) | n大時較好 |
二,演算法的空間複雜度
一個演算法的空間複雜度(Space Complexity)S(n)定義為該演算法所耗費的儲存空間,它也是問題規模n的函式。漸近空間複雜度也常常簡稱為空間複雜度。
空間複雜度(Space Complexity)是對一個演算法在執行過程中臨時佔用儲存空間大小的量度。一個演算法在計算機儲存器上所佔用的儲存空間,包括儲存演算法本身所佔用的儲存空間,演算法的輸入輸出資料所佔用的儲存空間和演算法在執行過程中臨時佔用的儲存空間這三個方面。演算法的輸入輸出資料所佔用的儲存空間是由要解決的問題決定的,是通過引數表由呼叫函式傳遞而來的,它不隨本演算法的不同而改變。儲存演算法本身所佔用的儲存空間與演算法書寫的長短成正比,要壓縮這方面的儲存空間,就必須編寫出較短的演算法。演算法在執行過程中臨時佔用的儲存空間隨演算法的不同而異,有的演算法只需要佔用少量的臨時工作單元,而且不隨問題規模的大小而改變,我們稱這種演算法是“就地\"進行的,是節省儲存的演算法。
當一個演算法的空間複雜度為一個常量,即不隨被處理資料量n的大小而改變時,可表示為O(1);當一個演算法的空間複雜度與以2為底的n的對數成正比時,可表示為0(10g2n);當一個演算法的空I司複雜度與n成線性比例關係時,可表示為0(n).若形參為陣列,則只需要為它分配一個儲存由實參傳送來的一個地址指標的空間,即一個機器字長空間;若形參為引用方式,則也只需要為其分配儲存一個地址的空間,用它來儲存對應實參變數的地址,以便由系統自動引用實參變數。