目錄python
/* 僞代碼描述 */ void SelectionSort (int List[], int N) { 將N個整數List[0]...List[N-1]進行非遞減排序; 從List[i]到List[N-1]中找最小元,並將其位置賦給MinPosition; 將未排序部分的最小元換到有序部分的最後位置; } }
/* c語言實現 */ void SelectionSort (int List[], int N) { /* 將N個整數List[0]...List[N-1]進行非遞減排序 */ for (i=0; i<N; i++){ MinPosition = ScanForMin(List, i, N-1); /* 從List[i]到List[N-1]中找最小元,並將其位置賦給MinPosition;*/ Swap(List[i], List[MinPosition]); /* 將未排序部分的最小元換到有序部分的最後位置; */ } }
# python語言實現 def selection_sort(lt, n): for i in range(n): min_position = scan_for_min(lt, i, n-1) swap(lt[i], lt[min_position])
抽象 ——算法
List到底是數組仍是鏈表(雖然看上去像數組)?數組
Swap用函數仍是用宏去實現?函數
一般經過下面兩個指標衡量算法的好壞spa
根據算法寫成的程序在執行時佔用存儲單元的長度。這個長度每每與輸入數據的規模有關。空間複雜度太高的算法可能致使使用的內存超限,形成程序非正常中斷。設計
根據算法寫成的程序在執行時耗費時間的長度。這個長度每每也與輸入數據的規模有關。時間複雜度太高的低效算法可能致使咱們在有生之年都等不到運行結果。code
/* c語言實現 */ void PrintN (int N) {if (N){ PrintN(N - 1); printf("%d\n", N); } return; }
# python語言實現 def print_n(n: int): if n: print_n(n - 1) print(n)
首先內存記錄PrintN(100000)
的狀態,但因爲是遞歸調用,會繼續記錄PrintN(99999)
的狀態,因爲繼續在遞歸調用,會繼續記錄PrintN(99998)
的狀態,……所以內存佔用超限。blog
\[ f(x) = a_0+a_1x+\cdots+a_{n-1}x^{n-1}+a_nx^n \]排序
對於上述的多項式,咱們可使用如下代碼實現:遞歸
/* c語言實現 */ double f(int n, double a[], double x) {int i; double p = a[0] for (i=1; i<=n; i++) p += (a[i] * pow(x, i)); /* pow會執行i次乘法 */ return p; }
# python語言實現 def f(n: int, a_list: list, x: float): p = a_list[0] for i in range(1, n): p += (a_list[i] * pow(x, i)) return p
時間複雜度:
\[ \begin{aligned} & (1+2+\dots+n)= (n^2+n)/2 \\ & T(n) = C_1n^2+C_2n \end{aligned} \]
可是上述的方法極其複雜,咱們能夠對多項式進行以下化簡:
\[ f(x) = a_0+x(a_1+(x(\cdots(a_{n-1}+x(a_n))\cdots)) \]
/* c語言實現 */ double f(int n, double a[], double x) {int i; double p = a[n]; for (i=n; i>0; i--) p = a[i-1] + x*p; /* 一次乘法 */ return p }
# python語言實現 def f(n: int, a_list: list, x: float): p = a_list[n] for i in range(0,n,-1): p = a_list[i-1] + x*p return p
時間複雜度:
\[ \begin{aligned} & (1+1+\dots+1)\quad\text{n次} \\ & T(n) = Cn \end{aligned} \]
綜上:在分析通常算法的效率時,咱們常常關注下面兩種複雜度
因爲平均複雜度的計算難度遠遠大於最壞狀況複雜度,所以一般考慮最快狀況複雜度,即\(T_{worst}(n)\geq{T_{avg}(n)}\)
對於算法的複雜度,沒有必要求出一個精確值,只須要粗略的知道算法的增加趨勢便可。
分析算法效率時,咱們老是但願找到\(O\)時最大的上界;找到\(\Omega\)時最小的下界。
下面三張圖表示算法複雜度爲不一樣函數時對應的耗時:
綜上:一個專業的程序猿,設計了一個\(O(N^2)\)的算法,應該本能的想到是否能把他改進爲\(O(Nlog_N)\)的算法。
若\(T(n)\)是關於\(n\)的\(k\)階多項式,那麼\(T(n)=\Theta{(n^k)}\)
if-else結構的複雜度取決於if的條件判斷複雜度和兩個分支部分的複雜度,整體複雜度取三者中最大