數據結構學習筆記系列2
視頻網址: https://www.bilibili.com/video/av18586085
彙總貼鏈接:https://blog.csdn.net/DX5618258/article/details/104085229
1.2.1算法的定義
算法(Algorithm)的定義如下:
- 一個有限指令集;
- 接受一些輸入(有些情況下不需要輸入);
- 產生輸出;
- 一定在有限步驟之後終止;
- 每一條指令必須:
1.有充分明確的目標,不可以有歧義;
2.計算機能處理的範圍之內;
3.描述應不依賴於任意一種計算機語言及具體實現手段
例1:選擇排序算法的僞碼描述
void SelectionSort( int List[ ] , int N )
{
/*將N個整數List[0]…List[N-1]進行非遞減排序*/
for( i = 0 ; i < N ; i++ )
{
從List[i]到List[N-1]中找最小元,並將其位置賦值給MinPosition;
將未排序部分的最小元換到有序部分的最後位置;
}
}
以上描述就有一定的不明確性,即描述有歧義,如:哪裏是有序部分?那裏是最後位置?
void SelectionSort( int List[ ] , int N )
{
/*將N個整數List[0]…List[N-1]進行非遞減排序*/
for( i = 0 ; i < N ; i++ )
{
/*從List[i]到List[N-1]中找最小元,並將其位置賦值給MinPosition;*/
MinPosition = ScanForMin(List , i , N-1);
/*將未排序部分的最小元換到有序部分的最後位置;*/
Swap( List[i] , List[MinPosition] );
}
}
抽象的地方:List到底是數組還是鏈表;Swap是函數還是宏;
以上抽象的部分在算法的描述的過程中均不關心。
1.2.2 什麼是好的算法
衡量算法好壞的量度:
空間複雜度S(n)——根據算法寫成的程序在執行時佔用存儲單元的長度。
這個長度往往與輸入數據的規模有關。空間複雜度過高的算法可能導致使用的內存超限,造成程序非正常中斷。
時間複雜度T(n)——根據算法寫成的程序在執行時耗費時間的長度。
這個長度往往也與輸入數據的規模有關。時間複雜度過高的低效算法可能導致我們在有生之年都等不到運算結果。
例:下圖例2爲遞歸算法輸出連續整數;例3爲計算多項式的兩種方法
例2所示遞歸程序需要從最內層的函數開始計算,在這之前需要將外層的所有部分依次存入內存,導致運行時佔用內存過高,進而導致程序在佔用內存達到一定程度的時候直接崩潰。
例3所示的兩種計算多項式的程序中,第一個的算法需要 ((n^2+n))⁄2次乘法,第二個算法需要n次乘法,當n足夠大時,第二種算法就會比第一種算法節省很多時間。
在分析算法的效率時,經常關注的兩種複雜度:
最壞情況複雜度 T_worst (n) ; 平均複雜度 T_avg (n)
易知: T_avg (n)≤T_worst (n)
1.2.3 複雜度的漸進表示
複雜度的漸進表示法
計算複雜度的時候沒有必要獲取精確地值,只需要粗略的瞭解其增長趨勢即可。
即O(f(n))爲複雜度上界,Ω(g(n))爲複雜度下界,Θ(h(n))表示複雜度的上界和下界均爲此值。
不同複雜度函數的增長速度:
下圖爲計算機指令運行時間表:
複雜度分析竅門: