????什么是数据结构?
????数据结构是研究非数值计算的程序设计中计算机的操作对象以及它们之间的关系和操作的学科。
一、数据结构的研究内容及基本概念和基本术语
????掌握数据、数据元素、抽象数据类型、数据结构、数据的逻辑结构与存储结构等概念。
-
数据:是客观事物的符号表示,是所有能输入到计算机中并被计算机处理的符号的总称。 例如一个学生信息大全的所有信息称为数据。 -
数据元素:是数据的基本单位,它通常被看作一个整体进行考虑与处理。有时称为结点、顶点或记录等。 例如:一个学生的所有信息称为数据元素。 -
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。 例如:一个学生的学号称为数据项。 -
数据对象:是性质相同的数据元素的集合,是数据的子集。 例如:{‘A’、‘B’、‘C’}称为数据对象。 -
数据结构:是相互之间存在一种或多种关系的数据元素的集合。换句话说,数据结构是带“结构”的数据元素的集合,“结构”是数据元素之间存在的关系。 -
逻辑结构:数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。并且可以看作是具体问题抽象出来的数学模型。
- 存储结构:数据对象在计算机中的存储表示称为数据的存储结构,也称为物理结构。存储结构分为顺序结构和链式结构。
(1) 顺序结构:顺序存储结构借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系,在存储器中需要连续的存储空间。 (2)链式结构:链式存储结构无需占用连续的存储空间,但是为了表示数据元素之间的关系,需要给每个数据元素附加地址字段,用于存放后继元素的存储地址。优点:不会占用太大的内存空间。缺点:查找信息不方便,耗时长。
-
按某种逻辑关系组织起来的一批数据(或称带结构的数据元素的集合)应用计算机语言并按一定的存储表示方式把它们存储在计算机的存储器中,并在其上定义了一个运算的集合。数据结构包含三个方面的内容,即数据的逻辑结构,数据的存储结构和对数据进行的运算(操作)。 -
三方面的关系: (1)数据的逻辑结构独立于计算机中,是数据本身所固有的。 (2)存储结构是逻辑结构在计算机存储器的映像,必须依赖于计算机。(因为既要存储各数据元素的数据,又要数据元素之间的逻辑关系)。 (3)运算是指所施加的一组操作的总称。 -
逻辑结构的形式定义是一个二元组:Data-Structure=(D,S),其中D是数据元素的有限集,S是D上关系的有限集。 注:D上的关系S可以用序偶来表示:<x,y>(x,y属于D)。x元素为y元素的直接前驱,y元素为x元素的直接后继。
数据类型
- 数据类型指的是一个值的集合和定义在这个值集上的一组操作的总称。
- 类型明显地规定了数据的取值范围、存储方式以及允许进行的计算,这些我们在学习C语言中都能够体会的到。
数据结构的主要运算(基本操作算法)包括:建立、消除、删除、插入、访问、修改、排序、查找。而书上总结的只有查找、插入、修改、删除。
抽象数据类型(ADT)
- 抽象数据类型指的是一个由用户定义、表示数学应用问题的数学模型,以及定义在这个模型上的一组操作的总称。
- 抽象数据类型的形式定义分为三部分:数据对象(D)、数据对象上关系的集合(S)以及对数据对象的基本操作的集合(P)。
ADT抽象数据类型名{
数据对象:<数据对象的定义>
数据关系:<数据关系的定义>
基本操作:<基本操作的定义>
} ADT抽象数据类型名
下面就给出复数的存储表示和相应的操作的具体实现过程。也可以参考书上用结构体的过程实现。
ADT complex{
数据对象:D={real, image | real∈实数, image∈实数}
数据关系:R={<real,image>}
基本操作:
InitComplex(&C)
操作结果:构造一个复数。
GetReal(C, &real)
初始条件:复数C存在。
操作结果:用real返回复数C的实部。
GetImage(C, &image)
初始条件:复数C存在。
操作结果:用image返回复数C的虚部。
OutputComplex(C)
初始条件:复数C存在。
操作结果:输出复数C的值。
Add(C1,C2,&C)
初始条件:复数C1,C2存在。
操作结果:用复数C返回复数C1,C2的和。
Sub(C1,C2,&C)
初始条件:复数C1,C2存在。
操作结果:用复数C返回复数C1,C2的差。
}ADT Complex
二、算法、时间复杂度、空间复杂度
算法
????是为了解决某类问题而规定的一个有限长的操作序列。
-
算法必须要有以下5个特性: (1)有穷性:有限步后要能结束,不能死循环。 (2)确定性:每条指令有确切含义,相同的输入有相同的结果,不会产生二义性。 (3)可行性:每个操作都能经过有限次基本运算完成。 (4)输入:算法可以没有输入。 (5)输出:算法一定有输出。 -
评价算法准则: (1)正确性:能够得到问题正确的解 (2)可读性:便于人对算法的理解 (3)健壮性:对于非法数据能给出处理 (4)高效率低存储:执行速度快,消耗空间少。这两者是矛盾的,需要平衡。 -
算法效率度量 度量程序执行时间有两种方法,一是事后统计,即将算法编写为程序,在计算机上运行得到运行的时间。但执行时间与计算机性能有关,容易掩盖算法本身的优劣。所以通常使用事前估算法。
时间复杂度
??????算法执行时间=一次简单操作时间*执行次数,由于一次简单操作时间受计算机性能影响,所以衡量算法效率,主要看执行次数多少。并且我们不需要求出精确次数,而只需要求出某个函数f(n),使得当n充分大时,时间增长率与f(n)增长率相同,即T(n) = O( f(n) ) 。计算时间复杂度主要分为两个步骤:先分析哪条语句是语句频度最大的语句,再计算循环执行多少次求出时间复杂度。
??????熟记不同时间复杂度的大小关系:
???????时间复杂度运算我们需要掌握两条法则:
加法法则: 乘法法则: 因为一个算法的平均时间复杂度难以确定,因此,通常只讨论算法在最坏情况下(即取循环次数最多)的时间复杂度,即分析在最坏情况下,算法执行时间的上界。
求下列程序的时间复杂度:
例题:
void fun(int n)
{
int i =1;
while(i<=n)
{
i = i*2;
}
}
???????循环看似执行n次,但因为循环变量每次都*2,循环执行x次后,i最后可以看为2的x次方,2的x次方<=n,则能计算出x为log2的n次,所以时间复杂度为f(n)=O(log2的n次)。
例题:(立方阶)
for(i=1;i<=n;i++)
for(j=1;j<=i;j++)
for(k=1;k<=j;k++)
x++;
???????这条程序的语句频度最深的毫无疑问是x++,我们观察嵌套最深的for循环的条件,k从1到j,则执行了j次,第二层循环中,j从1到i,则要算出1到i等差数列的和,即2分之i(i+1),最外层循环中i从1到n,循环n次,算出1到n的和代入到第二层结果的i中,则结果能够算出最终结果。参考书本14页最上方。
空间复杂度
该算法所耗费的存储空间,这个空间指的是额外的辅助空间。
???????这里第一章只重点考察时间复杂度,计算空间复杂度相对简单,看书上例题即可,在此处不再说明。
总结
???????因为第一章涉及概念与术语比较多,一定要尽力地去背诵,去了解数据结构的大致内容,此后作者还会持续更新对《数据结构》后面知识的知识梳理,请持续关注。如果本篇文章让您对数据结构的入门有帮助,麻烦点个赞谢谢!
|