数据结构学习笔记(二)
基于陈越姥姥的《数据结构》
什么是算法?
算法定义(Algorithm)
- 一个有限的指令集
- 接受一些输入(有些情况下不需要输入)
- 产生输出
- 一定在有限步骤之后终止
- 每一条指令必须
- 有充分明确的目标,不可以有歧义
- 计算机能处理的范围之内
- 描述应不依赖与任何一种计算机语言以及具体的实现手段
例1:选择排序算法的伪码描述
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] );
/* 置 将未排序部分的最小元换到有序部分的最后位置 */
}
}
抽象 —
list 到底是数组还是链表
Swap用函数还是宏去实现?
什么是好的算法
- 空间复杂度 S(n) —根据算法写成的程序在执行时占用存储单元的长度。这个长度往往与输入数据的规模有关。空间复杂度过高的算法可能导致使用的内存超限,造成程序非正常中断。
- 时间复杂度 T(n) —根据算法写成的程序在执行时耗费时间的长度。这个长度往往也与输入数据的规模有关。时间复杂度过高的低效算法可能导致我们在有生之年都等不到运行结果。
例2:关于空间复杂度
/*关于递归算法数据量过大崩溃的问题*/
void PrintN ( int N )
{ if ( N ){
PrintN( N – 1 );
printf(“%d\n”, N );
}
return;
}
/*
PrintN(100000)
PrintN(99999)
PrintN(99998)
PrintN(99997)
........
PrintN(0)
*/
空间复杂度: S(N)=C⋅N
例2:关于时间复杂度
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));
return p;
}
时间复杂度: (1+2+3+.....+n)=(n2+n)/2 次乘法, T(n)=C1n2+C2n
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;
}
时间复杂度: n 次乘法,
在分析一般算法的效率时,我们经常关注下面两种复杂度
最坏情况复杂度