本文章记录《数据结构》的第一章,绪论部分,也就是一些基本概念以及时间复杂度和空间复杂度
基本概念和术语
数据(Data)是客观事物的符号表示,是所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素(Data Element)是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
数据项(Data Item)是组成数据元素的、有独立含义的、不可分割的最小单位。
数据对象(Data Object)是性质相同的数据元素的集合,是数据的一个子集。
数据结构
数据结构(Data Structure)是相互之间存在一种或多种特定关系的数据元素的集合。
数据结构的一个简陋的草图:
算法与算法分析
算法与数据结构存在着本质的联系。
算法(Algorithm)是为了解决某类问题而规范的一个有限长的操作序列。
一个算法的五个特性:有穷性、确定性、可行性、输入、输出
算法优劣的基本标准:正确性、可读性、健壮性、高效性。
在这里解释一下健壮性和高效性
书中对健壮性的解释是:当输入的数据非法时,好的算法能适当地做出正确反应或进行相应处理,而不会产生一些莫名其妙的输出结果。
高效性比较重要:高效性包括时间和空间两个方面。时间高效是指算法设计合理,执行效率高,可以用时间复杂度来度量;空间高效是指算法占用存储容量合理,可以用空间复杂度来度量。
时间复杂度和空间复杂度是衡量算法的两个重要指标。
衡量算法效率的方法主要分为两类:事后统计法和事前统计法。
事后统计法需要先实现,然后测算。缺陷明显:1、必须先把算法转化成可执行的顺序;2、时空开销的测算结果依赖于计算机的软硬件实现。
所以,我们通常使用事前分析估算法,通过计算算法的渐进复杂度来衡量算法效率。
时间复杂度
T(n)=O( f(n) )
时间复杂度,理解起来确实复杂
我们先来理解一个概念:语句频度(Frequency Count)
一条语句的重复执行次数作为语句频度
解释起来太复杂,大致意思频度叠加,给个例子
for (int i = 0; i <=n ; i++) { //频度为n+1
for (int j = 1; j <=n; j++) { //频度为n*(n+1)
c[i][j]=0; //频度为n*n
for(int k = 1; k<=n; k++) //频度为n*(n+1)*n
c[i][j]=c[i][j]+a[i][j]; //频度为n*n*n
}
}
这里的 f(n)就是所有的频度加起来
公式推理应用到数学,简单理解就是最大的语句频度*,就是时间复杂度。所以,时间复杂度最重要的就是求语句频度
上面的时间复杂度就是
T(n)=O(n * n * n)
n* n*n是n的三次方,我打不出来。。。。。。
给几个例子
- 常量阶
{x++;s=0;}
里面二条语句频度均为1
所以,T(n)=O(1)
- 线性阶
for(i=0;i<n;i++){
x++;
s=0;
}
循环体内二条语句频度均为n
所以,T(n)=O(n)
- 平方阶
x=0;y=0
for(k=1;k<=n;k++)
x++;
for(i=1;i<=n;++){
for(j=1;j<=n;j++){
y++;
}
}
可以看出,出现最多的语句是y++,因为i=j=1,所以这条语句的频度为n*n
所以,T(n)=O(n * n)
掌握了诀窍,让我们看看复杂的
- 立方阶
x=1;
for(i=1;i<=n;++){ //频度n
for(j=1;j<=i;j++){ //频度n(n+1)/2
for(j=1;j<=j;k++){ //频度n(n+1)(n+2)/6
x++;
}
}
}
可以看得出,语句频度最高的是里面的x++; ,但是这次数。。。
算出上面三个的语句频度,不知道x++的频度为什么是这个,
书中的答案是:[n(n+1)(2n+1)/6+n(n+1)/2]/2
不管怎么样,都是T(n)=O(n * n * n)
- 对阶
for(i=1;i<=n;i=i*2){x++;y++}
同样的,知道里面的语句频度就行,这个就容易了,i每次都乘以2,设频度为f(n),则:2的f(n)次方<=2,所以f(n)<=log2n (2是下面的小的)
所以:T(n)=O(log2n)
书中举得例子都是一些简单的例子,还有一些更复杂的,计算需要有些高中数学的知识
空间复杂度
空间复杂度(Space Complexity)就简单很多阿,也是采用渐近式作为作为主要算法的
S(n)=O(f(n))
直接给出简单的例子:
算法1
for(i=1;i<n/2;++){
t=a[i];
a[i]=a[n-i-1];
a[n-i-1]=t;
}
算法2
for(i=1;i<n;++){
b[i]=a[n-i-1];
for(i=1;i<n/2;++){
a[i]=b[i];
}
}
算法1空间复杂度为 O(1)
算法2空间复杂度为 O(n)
在这里空间复杂度并不是程序的指令、常数、变量和输入数据所占用的空间,而是一些对数据进行操作的辅助存储空间。
时间复杂度与空间复杂度相互影响,当最求一个好的时间复杂度时,可能导致占用较多的存储空间,即空间复杂度变差,反之亦然。
通常情况下,鉴于空间较为充足,往往都以时间复杂度作为算法优劣的衡量指标。