一、数据结构的基础概念
1. 数据(Data)
数据是描述客观事物的数值、字符以及能输入机器且能被处理的各种符号集合。
- 狭义上:数据类型有整型、实型、布尔型等数值。
- 广义上:数据已由纯粹的数值概念发展为图像、字符、声音等各种符号。
2. 数据元素(Data Element)
数据元素是组成数据的基本单位,是数据集合的个体。
数据项是有独立含义的最小单元,
此时的数据元素通常称为记录。
上述学籍表是数据,每一个学生的记录(即每一行)就是一个数据元素。
一个数据元素由一个或多个数据项组成。(上述一个数据元素由“学号”,“姓名”等数据项组成)。
3. 数据对象(Data Object)
数据对象是性质相同的数据元素的集合,是数据的一个子集。
例如:有限集(如字符集)、无限集(如整数集),还是由多个数据项组成的复合数据元素(如上述学籍表)都是数据对象。
4. 数据概念归纳
5. 数据结构的内容(Data Structure)
数据结构是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素集合,是带有结构的数据元素的集合,它指的是数据元素之间的相互关系,即数据的组织形式。
数据结构要研究数据元素之间的相互关系与组织方式,以及对其施加的运算及运算规则,并不关心数据元素的具体内容是什么值。
6. 数据类型(Data Type)
数据类型是一组性质相同的值集合以及定义在这个值集合上的一组操作的总称。
即数据类型中定义了两个集合:该类型的取值范围(定义域)和该类型中可允许使用的一组运算(操作集)。
例如:
在C语言中,整型类型的取值范围为-32767~+32768,可用的运算符集合为加、减、乘、除、取模。
6.1 数据类型的分类
按“值”的不同特性,一般来说,高级程序设计语言中的数据类型可分为两大类:
- 原子类型
原子类型的值是不可再分的,如:C语言中的整型、实型和字符型及指针。 - 结构类型
结构类型的值是由若干成分按某种结构组合而成的,因此是可以分解的,它的成分可以是原子的,也可以是结构的。如:数组的值由若干分量组成,每个分量可以是整型,也可以是数组等其他类型。
6.2 引入数据类型的目的
从硬件角度是将其作为解释计算机内存中信息含义的一种手段。
对使用数据类型的用户来说则实现了信息隐蔽,将一切用户不关心的细节封装在类型中。
例如:两整数求和,用户仅关注其数学求和的抽象特性,而不必关心加法运算设计的内部位运算实现细节。
7. 抽象数据类型
抽象的本质是抽取反映问题的本质点,而忽略非本质的细节,这是从事计算机研究的重要方法。
7.1 数据的抽象
汇编语言中十进制表示的数据98.65、9.6E3等,它们是二进制数据的抽象。
高级语言中,给出如整型、实型、字符型等更高一级的数据抽象,还可以进一步定义如各种表、队、栈、树、图、窗口、管理器等复杂的抽象数据类型。
7.2 抽象数据类型
抽象数据类型(简称ADT)定义了一个数据对象,数据对象中各元素间的结构关系,以及一组处理数据的操作。
ADT包括定义和实现两方面,其中定义是独立于实现的。
二、数据结构的内容
1. 逻辑关系
数据的逻辑结构是指数据元素之间逻辑关系描述。
形式化描述:数据结构是一个二元组Data_Structure=(D,R)
其中D是数据元素的有限集,R是D上关系的有限集。
例如:
则其逻辑结构图位一颗树。
1.1 四类基本数据结构
- 集合结构:结构中的数据元素之间除了同属于一个集合的关系外,无任何其它关系。
- 线性结构:结构中的数据元素之间存在着一对一的线性关系。
- 树型结构:结构中的数据元素之间存在着一对多的层次关系。
- 网状结构:结构中的数据元素之间存在着多对多的任意关系。如:图。
2. 存储结构
存储结构(又称物理结构):是逻辑结构在计算机中存储映像,是逻辑结构在计算机中的实现,它包括数据元素的表示和关系的表示。
形式化描述:D要存入机器中,建立一个从D的数据元素到存储空间M单元的映像S,D->M,即对于每一个d,d属于D,都有唯一的z属于M使S(D)=Z,同时这个映像必须明显或隐含的体现关系R。
2.1 逻辑结构与存储结构的关系
存储结构是逻辑关系的映像与元素本身的映像。
逻辑结构是数据结构的抽象,存储结构是数据结构的实现,两者综合起来建立了数据元素之间的结构关系。
2.2 数据元素之间关系在计算机中的表示方法
- 顺序映像(顺序存储结构):连续存储
- 非顺序映像(非顺序存储结构):任意存储
3. 运算集合
讨论数据的目的是为了在计算机中实现操作,因此在结构上的运算集合是很重要的部分。
数据结构就是研究一类数据的表示及其相关的运算操作。
4. 数据结构的内容总结
例如:
上述工资表中,采用了线性表的逻辑结构,因为结点和结点之间是简单的线性关系;由于工资表包含很多职工,可采用顺序存放,也可采用非顺序结构存放;对于工资表,开除员工需要进行删减操作,这里的增、删、查、改就是数据的操作集合。
三、算法
1. 算法的定义
算法是规则的有限集合,是为解决特定问题而规定的一系列操作。
2. 算法的特性
3. 算法设计的要求
3.1 算法的正确性
3.2 可读性
一个好的算法首先应该便于人们理解和相互交流,其次才是机器可执行。
可读性好的算法有助于人对算法的理解,并且难懂的算法易于隐藏错误且难于调试和修改。
3.3 健壮性(鲁棒性)
即对非法输入的抵抗能力。
它强调的是,如果输入非法数据,算法应能加以识别并做出处理,而不是产生错误动作或陷入瘫痪。
3.4 高效率和低存储量
算法的效率通常是指算法的执行时间。执行时间越短,效率越高。
存储量是指算法在执行过程中所需要的最大存储空间。
这两者都与问题的规模有关。
四、算法描述
概述:算法+数据结构=程序
1. 算法、语言、程序的关系
算法:规则的有限集合,是为解决特定问题而规定的一系列操作。
描述算法的工具:算法可用自然语言、框图或高级程序设计语言进行描述。
程序:是算法在计算机的实现。
2. 描述算法的语言选择
各种语言各有利弊,例如:高级语言描述算法具有严格、准确的优点,但用于描述算法,也有语言细节过多的弱点,为此采用类语言形式。
类语言:是接近于高级语言而又不是严格的高级语言。它具有高级语言的一般语句设施,撇掉语言中的细节,把注意力主要集中在算法处理步骤本身的描述上。
五、对算法性能评价
评价一个算法主要看这个算法所占用机器资源的多少,而这些资源中时间代价与空间代价是两个主要的方面,通常是以算法执行所需的机器时间和所占用的存储空间来判断一个算法的优劣。
- 性能评价:算法所占用机器资源主要表现在时间代价和空间代价两个方面。算法效率与问题规模N有关,算法效率应该是问题规模的函数。
- 问题规模N:反映问题大小的本质数目,对于不同的问题其含义不同:
例如:对矩阵是阶数;对图是顶点个数;对多项式运算是多项式项数。
1. 算法的时间性能分析
1.1 算法耗费的时间
一个算法的执行时间大致上等于其所有语句执行时间的综合,对于语句的执行时间是指该条语句的执行次数和执行一次所需时间的乘积。
由于算法的实际执行时间受机器硬件和系统软件等诸多环境因素影响,因此算法执行时间的本质信息应该是针对算法中语句执行次数做出估计。
1.2 语句频度
语句频度:是指该语句在一个算法中重复执行的次数。
1.3 算法的时间复杂度
即算法的时间量度,以语句频度为量度。
记作:T(n) = O(f(n))
1.4 渐进时间复杂度
在算法分析时,常常将渐进时间复杂度简称为时间复杂度。
例如:T(n)=100n^2,它的渐进时间复杂度为O ( n ^2 )
f(n)一般是算法中频度最大的语句频度。
1.5 常用算法时间复杂度
1.6 最坏时间复杂度
讨论算法在最坏情况下的时间复杂度,即分析最坏情况下以估计出算法执行时间的上界。
2. 算法的空间性能分析
2.1 算法耗费的空间
一个算法的占用空间是指算法实际占用的辅助空间总和。
2.2 算法的空间复杂度
S(n) = O(f(n))
六、数据结构与C语言表示
1. 数据结构与程序设计的关联性
选择最佳的数据结构并提供策略方法有效的利用这些数据,便于达到高效、低耗的解决问题。
例如:求学生的测试成绩时,采用数组结构存储测试成绩,可以提高程序的使用范围。
2. 结构化程序设计与函数模块化
著名的计算机科学家wirth(沃思)提出了一个著名的公式表达了程序设计的实质:算法+数据结构=程序。即“程序是在数据的特定表示方式的基础上,对抽象算法的具体描述”。
程序结构=控制结构+数据结构
结构化程序设计是为使程序具有合理的结构,以保证程序正确性而规定的一套程序设计的方法,使人们多年来研究与实践的结晶。
3. 用C语言实现抽象数据类型ADT
3.1 ADT的定义格式
ADT包括对象、关系、操作三个部分,其定义格式可以有多种。如下:
ADT<ADT名>
{数据对象:<数据对象的定义>
结构关系:<结构关系的定义>
基本操作:<基本操作的定义>
}ADT<ADT名>
其中:
- 数据对象定义应在已有数据类型或已定义数据对象基础上对新的数据对象的定义。
- 数据对象和数据关系的定义采用数学符号和自然语言描述。
- 基本操作定义包括操作名称、参数表、初始条件和操作结果4部分内容。
基本操作的定义格式为:
<操作名称>(参数表)
操作前提:<操作前提描述>
操作结果:<操作结果描述>
3.2 用C语言实现ADT
主要包括以下两个方面:
- 通过结构体将int、float等固定类型组合到一起,构成一个结构体类型,再用typedef为该类型或该类型指针重新起一个名字,以便增强程序的抽象性、简洁性和可读性。即采用C语言中关键字typedef自定义类型来实现。
- 用C语言的子函数实现各个操作。
4. 算法描述规范与设计风格
4.1 算法表示格式
4.2 函数模块化
根据结构化程序设计思想,将一个大任务分解成若干个功能独立的子任务,故程序可由一个主函数和若干个子函数构成。
每个函数具有独立功效,一旦修改某个函数不影响其它函数运作。
5. 与参数传递的相关技术
5.1 变量的作用域
- 全局变量:程序中所有函数都可以访问的量。
- 局部变量:只能在该函数中访问的量。
5.2 参数传递方式
传值:实参代替形参的一个单向传值过程。
传址:指针类型的参数传递。
5.3 函数结果的带出方式
函数结果共有全程量、函数返回值、传址参数三种带出方式。
通过参数表的参数传递是一种参数显示传递方式,而通过全局变量是一种隐式参数传递的方式。
5.4 思考
值传递方式中,如果返回一个结果值,可以使用return返回方式带出一个函数结果值。若函数结果需要多个带出值,该怎样实现?
- 全局变量方式
- 数组方式
- 结构体方式
- 指针方式
七、关于学习数据结构
1. 数据结构课程的地位
2. 数据结构课程学习特点
- 教学目标:学会分析数据对象的特征,掌握数据组织方法和计算机的表示方法,以便为应用所涉及数据选择适当的逻辑结构、存储结构及相应算法,初步掌握算法时间空间分析技巧、培养良好的程序设计技能。
八、总结与提高
-
数据结构的基本概念
-
算法与算法分析
-
注意逻辑结构与存储结构区别
-
面向对象概念:理解数据类型、抽象数据类型、数据抽象和信息隐蔽规则,了解面向对象的含义。
如有问题,欢迎批评指正呀!