目录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的条件判断复杂度和两个分支部分的复杂度,整体复杂度取三者中最大