文章目录
前言
数据结构的绪论,一些数据结构的学习和研究所涉及的基本知识和概念。
1 什么是数据结构学科
1.1 程序设计的实质是:对确定的问题选一个好的结构,加上一种好的算法。
即“程序 = 算法 + 数据结构”。
选一个好的结构,即从具体问题抽象出一个适当的数学模型。
加一种好的算法,即设计或选择一个解此数学模型的算法。
1.2 早期计算机所涉及的计算的数学模型多是数值型,无需重视数据的逻辑关系和存储结构。
随着计算机应用领域的扩大和软、硬件技术的发展,非数值计算问题显得越来越重要。
描述非数值计算问题的数值模型不再是数学方程或数学公式,而是诸如表、图、树之类的数据结构。
因此,简单地说,数据结构是一门研究如何用计算机求解非数值计算问题的学科。
2 基本概念和术语
2.1 数据与数据元素
2.1.1 数据(data)是对客观事物的符号表示,它能被计算机识别、存储和加工处理,
其中有意义的或从中加工出的即——信息。它是计算机计算的“原料”。
2.1.2 数据元素(data element)是数据的基本单位,有时也称为元素、结点或记录。
数据项是最小标识单位,有时也称为字段、域或属性。
一个数据元素可由若干数据项(data item)组成。
例如:数据元素(数据项…)——人(姓名,性别,身份证号…)。
2.2 数据的逻辑结构:数据之间的逻辑关系。
数据的逻辑结构是根据实际问题抽象出来的数学模型。
常用的逻辑结构:
(1)集合:任何两个元素之间都没有逻辑关系,每个元素都是孤立的。
(2)线性结构:结构中的元素之间存在一对一的关系,即线性关系。各元素排列成一个表,一个元素紧跟着另一个元素,整个结构像一条“链”。
(3)树状结构:结构中的元素之间存在一对多的关系。像自然界中倒长的“树”一样,呈分支、层次状态。
(4)图状结构:结构中的元素之间存在多对多的关系,即元素间的逻辑关系是任意的,也称邻接关系。
通常将树状结构、图状结构归纳为非线性结构。
2.3 数据的物理结构:数据在计算机内的存储方式。
逻辑结构在计算机内的具体实现。
基本的物理结构:
(1)顺序存储结构:数据元素依次存储在一组连续的存储单元中,逻辑关系由存储位置直接体现。常用一维数组实现,主要用于线性结构。
(2)链式存储结构:数据元素存储在一组任意的存储单元中,附加的指针表示元素之间的逻辑关系。常用指针变量来实现链式存储。
(3)索引存储结构:存储数据元素的同时,建立附加的索引表。索引表中每一项为索引项,一般形式为:(关键字,地址)。关键字是指能唯一标识数据元素的数据项,地址指向若干元素。
(4)散列存储结构:依据数据元素的关键字,使用一个事先设计好的函数计算出地址,然后存入它。该函数称为散列函数,由该函数计算出的地址称为散列地址。
上述4种存储方式,既可单独使用,也可组合使用。逻辑结构确定后,物理结构的选择,根据具体问题而定,主要考虑是运算方便、算法效率的要求。
2.4 数据运算:对数据施加的操作
在逻辑结构上定义,在物理结构上实现。
基本的运算有:
检索(查找)、插入、删除、更新、排序等。
2.5 数据结构(data structure):数据元素之间的相互关系,即数据的组织形式。
包含:
(1)数据的逻辑结构:数据元素之间的逻辑关系。它独立于计算机,是数据本身固有的。
(2)数据的物理结构:数据元素及逻辑关系在计算机存储器内的表示方式。它是逻辑结构在计算机存储器中的映射,必须依赖于计算机。
(3)数据运算:对数据元素施加的操作。运算的定义直接依赖于逻辑结构,但运算的实现必须依赖于物理结构。
同一逻辑结构,不同存储结构,得到的是不同的数据结构。
例如,线性结构,采用顺序存储,为顺序表;采用链式存储,为链表。
同一逻辑结构,不同运算,得到的是不同的数据结构。
例如,线性结构,插入、删除在一端,为栈;插入在一端,删除在另一端,为队列。
2.6 补充:数据类型和抽象数据类型
2.6.1 数据类型(data type):一个值的集合和在这个集合上定义的一组操作的总称。可以把数据类型看做是程序设计语言已实现的数据结构。
例如,C语言中的整型变量,其值集为某个区间上的整数,定义在其上的操作为加、减、乘、除和取模等运算。
按“值”可否分解,可把数据类型分为两类:
(1)原子类型:其值不可分解,如C语言中的基本类型(整型、实型、字符型、枚举型)、指针类型和空类型。
(2)结构类型:其值可分解为若干成分(或分量),如C语言的数值类型、结构类型等。结构类型的成分可以是原子类型,也可以是结构类型。
引入数据类型的目的:
(1)从硬件角度,解释计算机内存中信息的含义。
(2)从用户角度,实现了信息的隐藏,即将一切用户不必了解的细节封装在类型中。只需要知道怎么使用,而不需要了解底层实现细节。
2.6.2 抽象数据类型(abstract data type,ADT):一个数学模型以及定义在该模型上的一组操作的总和,它是一个概念。抽象数据类型的定义取决于它的一组逻辑特性,而与其在计算机内部如何表示和实现无关。“抽象”的意义在于数据类型的数学抽象特性。
抽象数据类型的范畴更广,不局限于已定义的数据类型,还包括用户在设计软件系统时自定义的数据类型。
面向对象的程序设计方法,即抽象数据类型的具体实现:
在构成软件系统的每个相互独立的模块上,定义一组数据和实施于这些数据上的一组操作,并在模块的内部给出这些数据的表示及其操作的细节,而在模块的外部使用的只是抽象的数据和抽象的操作。
3 算法和算法描述语言
数据运算是通过算法来描述的。
算法是对特定问题求解步骤的描述,是指令的有限序列,其中每条指令表示一个或多个操作。
算法的5个特性:
(1)有穷性:每步都可以在有限的时间内完成。
(2)确定性:每条指令必须有确切含义,不能有二义性。相同的输入,相同的输出。
(3)可行性:每步操作都能通过已实现的基本运算的有限次执行来实现。
(4)输入:有零个或多个输入。取自加工对象的集合。
(5)输出:有一个或多个输出。对输入加工后合乎逻辑的结果。
程序与算法十分相似,但程序不一定要满足有穷性。例如,操作系统是一个程序,但没有输入时仍处于等待循环中。
使用伪码语言的描述方法来进行算法描述,算法的书写格式:
<函数类型><函数名>([<参数表>])
/* 函数功能的简单说明 */
{
<语句系列>
}
其中[]表示方括号中的内容可缺省。一般而言,i、j、k常用作整型变量,p、q、r、s常用作指针变量。
4 算法的分析:评价算法的优劣。
算法衡量的4个指标:
- 正确性(correctness)
4层次的要求:
(1)算法没有语法错误。
(2)算法对几组输入能得出满足规格的结果。
(3)算法对精心选择的经典、苛刻的输入能得出满足规格的结果。
(4)算法对一切合法输入都能得出满足规格的结果。
一般满足第3层次的条件就认为合格。 - 可读性(readability)
要求算法便于人们阅读、交流和调试。
提高可读性的方法:
(1)注释:函数说明(功能、输入、返回值),代码行说明(if…end of if)。
(2)空行
(3)一行代码做一事
(4)对齐 - 健壮性
当输入非法时,算法能恰当地作出反应或进行处理,不会产生莫名其妙的输出。
进行合法性检查,并返回一个表示错误或错误性质的值,以便在更高的抽象层次上进行处理。 - 时空效率
要求时间复杂度和空间复杂度尽可能地小。
但时空要求往往是相互矛盾的,应在时间和空间两方面有所平衡。
作为算法衡量的主要指标。