1.概念
程序: 把人的语言转换成计算机的语言
算法:程序的处理过程,对结构进行CURD,但是不是任何结构都有CURD(如 queue stack没有插入)
数据类型: 数值(x=2y)和非数值(树)
数据类型: 对值的一组操作和有范围 int(有范围)
抽象数据类型:也是对值的操作 Object(有方法,有成员)
数据元素(类似java的对象)>数据项(java对象里的字段)
2.程序=算法+数据结构
3.什么是数据结构?
数据结构=logic(逻辑结构)+storage(存储结构)(存数据),用逻辑操作存储结构
逻辑结构的分类: (处理业务)
1.没有关系的集合
2.一对一 线性结构 (线性表有包含逻辑和存储结构)
3.一对多 树
4.多对多 图
存储结构的分类: (解决存储)
1.顺序存储(数组)
2.链式存储(指针指向下个数据)
4.算法的基本特性
1.有穷性(有穷时间完成,有限步骤)
2.确定性(上下文无关context,调用多少次都是一样的结果)
3.可行性(在已实现的基本操作和有代码实现)硬件支持(机器可执行)
5.什么是好算法?
1.正确性,任何合法输入都有正确的执行结果
2.健壮性(系统瘫痪) 非法输入有抵抗性,能处理(错误输入弹出提示框)
3.可理解性(算法可行,并且容易他人理解)如多个三元运算符嵌套,不利于他人理解
4.抽象分级 通过这个方法论来表示算法的实现过程(也是服务可理解性)
5.高效性 程序运行时 time减少 space减少
6.算法描述
1.自然语言描述(容易理解,但是有二义性,和代码相差很大) 如:
1.做xxx
2.做xxx
3.做xxx
2.流程图 直观但不灵活(不能改) 如 高中画的流程图
3.程序语言描述 优点:可以直观看到计算机执行结果 缺点:抽象性差,对语言要求高
4.伪代码(自然语言+代码) 算法需要去写成子函数验证 如: (下面我看不懂,必须要写好实现什么功能)
1. r=m%n;
2.循环直到 r=0
2.1 m=n;
3,输出 n
6.概念
算法设计(设计算法) <改进===评价>算法评价(评价优劣)
7.度量算法的方法
1.事后统计(定量分析)(某一台机器,算精确的时间 end-star)
2.事前分析(定性分析)估算时间复杂度和框架复杂度O(?) 估算到大概的范围
8.时间复杂度 执行时间和代码执行总次数成正比
O(1)<O(log2n)<O(n^2)< O(n ^ 3)<…O(2 ^ n) <O(n!)
例如:
void func(int n){
int i=0,s=0; //无穷大的时候相当于执行了0次
while(s<=n){
i++; //这里两句代码 看成执行一句代码
s=s+i;
}
}
分析过程为
代码执行次数T(n) 1 2 3 4 5
i 1 2 3 4 5
s 1 3 6 10 15
T(n)( T(n) + 1 )* 1/2 <=n
左边是求和公式,就是把所有执行次数加起来=代码执行总次数
右边是执行时间设为n
T(n)^2 + T(n) <=n // 1/2 可以忽略不计,
T(n)^2 <= n //T(n) 相比 T(n)^2 可以忽略不计
T(n) <= n^(1/2) //得出我们的时间复杂度是 O(^(1/2))
再举一个例子,假设n传入n,只会执行100句代码,时间复杂度为O(1)
for(i=0;i<n;i++){
if(i>100){ break; }
}
在举一个例子,三层for循环
int x=0;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
for(k=0;k<n;k++){
++x;
}
}
}
分析过程为:
T(n) 1 8 27 ..... //去网上找求和公式即可 1+8+27+...+n³=[n(n+1)/2]²
x 1 8
[T(n)(T(n)+1)/2]²<=n
T(n)^4 <=n
T(n) <= n^(1/4)
//这个怎么分析呢?
int i, j;
for(i = 0; i < n; i++){
for(j = i; j < n; j++){ /*注意j = i而不是0*/
/*时间复杂度为O(1)的程序步骤序列*/
}
}
总结:
复杂度就是 求一个 (全部输入的执行次数 n) 比上(设的时间n) 可以大概估算出时间范围
9.空间复杂度(度量存入数据大小,有没有开新空间,定义数组也算)
包括几个部分:
1.输入/输出的空间,函数参数(外部)传入不算
2.代码的空间
3.辅助的空间(新申请的空间 c语言使用malloc申请空间)
例子1: O(1)
func(int r[]){ //外来的输入 不算
for(){
//假设这里也没有申请新的空间,但是有操作空间
}
}
例子1: O(n)
func(int n){ //外来的输入 不算,但是他决定内部创建多少空间,就当不算吧
int r1[n]; //O(n)
for(){
//假设这里也没有申请新的空间,但是有操作空间
}
}
9.最好,最坏,平均情况
例子: 最好O(1),最坏O(n),平均情况O(n/2)=O(n) (这里分析的是for循环的if的时间复杂度)
int Find(int A[],int n,int k){
for(i=0;i<n;i++){
if(A[i]==k) break; //O(1)在n=0时只执行一次,在k如果是等于n时最坏为O(n)
}
return 1;
}