由于关于数据结构的概念和知识点过于繁乱,所以我今天就将其理了理,然后概括了一下本章我认为较重要的一些。
我们都知道计算机主要用于数值计算,而我们的数据结构主要研究非数值计算问题(大多为生活中遇到的问题)。
上图就是它们的基本关系,关于其基本概念什么的,在这里就不多说了。
其中存储结构又叫做物理结构,其中的顺序结构通常借助C语言中的数组类型来描述,而链式结构是借助C语言中的指针类型来描述的。
抽象数据类型:
抽象数据类型=数据的逻辑结构+抽象运算
定义格式:(主要使用类C语言)
ADT 抽象数据类型名{
Data
数据对象的定义
数据元素之间逻辑关系的定义
Operation
操作1
初始条件
操作结果的描述
操作2
操作n
}ADT 抽象数据类型名
举个复数例子:(类C语言)
ADT Complex{
D={r1,r2|r1,r2都是实数}
S={<r1,r2>|r1是实部,r2是虚部}
assign(&C,v1,v2)
初始条件:空的复数C已存在
操作结果:构造复数C,r1,r2分别被赋以参数v1,v2的值。
destroy(&C)
初始条件:复数C已存在
操作结果:复数C已销毁。
}ADT Complex
具体的代码实现在数据结构课本第十页有详细的讲解,在这里主要就是说一下&符号的作用,
在基本操作的定义格式:
基本操作名(参数表)
初始条件:(初始条件描述)
操作结果:(操作结果描述)
这里的参数表:1.赋值参数:只为操作提供输入值。
2.引用参数:以&开头,除可提供输入值外,还将返回操作结果。
比如将图形A放大十倍,我们可以再用一个A’来返回这个放大后的A,然而由于放大后的A仍然是一个图形,所以我 们还可以用A来返回放大后的,只需在其前面加一个&即可。
本章算法里面主要是一个时间和空间的复杂度。
时间复杂度:
时间复杂度是由嵌套最深层语句的频度决定的。
例1:
for(i=0;i<n;i++)
for(j=0;j<i;j++)
for(k=0;k<j;k++)
x++;
其时间复杂度为(n*(n+1)*(n+2))/6,即T(n)=O(n*n*n),这个需要记住(取最高次幂,将低次幂以及最高次幂的系数一并去掉)。
例2:
for(i=1;i<=n;i++)
i=i*2;
其时间复杂度为T(n)=O(logn)
因为:
语句执行1次;i=2
语句执行2次;i=4(2的平方)
语句执行3次;i=8(2的3次方)
语句执行m次;i=2的m次方
2的m次方<= n
m<=logn
另外对于
for(i=0;i<n;i++)
其时间复杂度为T(n)=O(n+1),之所以为n+1,是因为当i=n-1时,i++会继续执行,到i=n,才进行判断不满足条件i<n,所以i从0开始加到n,这条语句共执行了n+1次。
最好最坏复杂度:
此外
for(i=0;i<n;i++)
for(j=0;j<n;j++)
a[i][j]=0
这个时间复杂度取决于a[i][j]的位置,有可能一次就查找成功了(T(n)=O(1)),也有可能查找完所有的都没有成功(T(n)=O(n*n))
最好时间复杂度:T(n)=O(1)
最坏时间复杂度:T(n)=O(n*n)
一般总是考虑在最坏情况下的时间复杂度,以保证算法的运行时间不会比它更长。
对于复杂的算法可以将它分成几个容易估算的部分,然后利用加法和乘法法则,计算算法的时间复杂度
a.加法规则:
T(n)=T1(n)+T2(n)=O(f(n))+O(g(n))=O(max(f(n),g(n)) //取最大值
b.乘法法则;
T(n)=T1(n)*T2(n)=O(f(n))*O(g(n))=O(f(n)*g(n)) //直接相乘
时间复杂度的比较:(复杂度从小到大)
常量阶O(1)<对数阶O(logn)<线性阶O(n)<线性对数阶O(n*logn)<平方阶O(n*n)<立方阶O(n*n*n)<k次方阶(n的k次方)<指数阶(2的n次方)等。
空间复杂度:
例:逆序输出数组中的元素
1.空间复杂度S(n)=O(1),原地工作
for(i=0;i<n/2;i++)
{
int t=a[i];
a[i]=a[n-i-1];
a[n-i-1]=t;
}
2.空间复杂度S(n)=O(n),因开辟了新的数组,占用了空间
for(i=0;i<n;i++)
{
b[i]=a[n-i-1];
}
for(j=0;j<n;j++)
{
a[j]=b[j];
}