基本概念和术语
1、数据(Data)
数据是外部世界信息的载体,它能够被计算机识别、存储和加工处理,是计 算机程序加工的原料。计算机程序处理各种各样的数据,可以是数值数据,如整 数、实数或复数;也可以是非数值数据,如字符、文字、图形、图像、声音等。
2、数据元素(Data Element)和数据项(Data Item)
数据元素是数据的基本单位,在计算机程序中通常被作为一个整体进行考虑 和处理。数据元素有时也被称为元素、结点、顶点、记录等。一个数据元素可由 若干个数据项(Data Item)组成。数据项是不可分割的、含有独立意义的最小数据 单位,数据项有时也称为字段(Field)或域(Domain)。
3、数据对象(Data Object)
数据对象是性质相同的数据元素的集合,是数据的一个子集。
4、数据类型(Data Type)
数据类型是高级程序设计语言中的概念,是数据的取值范围和对数据进行操 作的总和。
5、数据结构(Data Structure)
数据结构是相互之间存在一种或多种特定关系的数据元素的集合。在任何问 题中,数据元素之间都不是孤立的,而是存在着一定的关系,这种关系称为结构 (Structure)。根据数据元素之间关系的不同特性,通常有 4 类基本数据结构:
(1) 集合(Set):如图 1.1(a)所示,该结构中的数据元素除了存在“同属于一个集 合”的关系外,不存在任何其它关系。
(2) 线性结构(Linear Structure):如图 1.1(b)所示,该结构中的数据元素存在着一 对一的关系。
(3) 树形结构(Tree Structure):如图 1.1(c)所示,该结构中的数据元素存在着一对 多的关系。
(4) 图状结构(Graphic Structure):如图 1.1(d)所示,该结构中的数据元素存在着 多对多的关系。
数据结构的形式化定义为:数据结构(Data Structure)简记为 DS,是一个二元组,DS = (D,R)
其中:D 是数据元素的有限集合,R 是数据元素之间关系的有限集合。
算法
算法与数据结构和程序的关系非常密切。进行程序设计时,先确定相应的数据结构,然后再根据数据结构和问题的需要设计相应的算法。由于篇幅所限,下面只从算法的特性、算法的评价标准和算法的时间复杂度等三个 方面进行介绍。
算法的特性
算法(Algorithm)是对某一特定类型的问题的求解步骤的一种描述,是指令的有限序列。其中的每条指令表示一个或多个操作。一个算法应该具备以下 5 个特性:
1、有穷性(Finity):一个算法总是在执行有穷步之后结束,即算法的执行时间是 有限的。
2、确定性(Unambiguousness):算法的每一个步骤都必须有确切的含义,即无二 义,并且对于相同的输入只能有相同的输出。
3、输入(Input):一个算法具有零个或多个输入。它即是在算法开始之前给出的量。这些输入是某数据结构中的数据对象。
4、 输出(Output):一个算法具有一个或多个输出,并且这些输出与输入之间存 在着某种特定的关系。
5、 能行性(realizability):算法中的每一步都可以通过已经实现的基本运算的有 限次运行来实现。
算法的评价标准
对于解决同一问题的不 同算法,选择哪一种算法比较合适,以及如何对现有的算法进行改进,从而设计出更适合于数据结构的算法,这就是算法评价的问题。评价一个算法优劣的主要标准如下:
1、正确性(Correctness)。
2、可读性(Readability)。算法主要是为了人阅读和交流,其次才是机器的执行。
3、健壮性(Robustness)。一个算法应该具有很强的容错能力,当输入不合法的数 据时,算法应当能做适当的处理,使得不至于引起严重的后果。
4、运行时间(Running Time)。运行时间是指算法在计算机上运行所花费的时间, 它等于算法中每条语句执行时间的总和。
5、占用空间(Storage Space)。占用空间是指算法在计算机上存储所占用的存储空 间,包括存储算法本身所占用的存储空间、算法的输入及输出数据所占用的存储 空间和算法在运行过程中临时占用的存储空间。
算法的时间复杂度
一个算法的时间复杂度(Time Complexity)是指该算法的运行时间与问题规模的对应关系。
如果一个算法没有循环语句,则算法中基本操作的执行频度与问题规模n无 关,记作O(1),也称为常数阶。如果算法只有一个一重循环,则算法的基本操作 的执行频度与问题规模n呈线性增大关系,记作O(n),也叫线性阶。常用的还有 平方阶O(n2 )、立方阶O(n3 )、对数阶O(log2n)等。
下面举例来说明计算算法时间复杂度的方法。
【例1-4】 分析以下程序的时间复杂度。 x=n; /*n>1*/ y=0; while(y < x) { y=y+1; //① } 解:这是一重循环的程序,while 循环的循环次数为 n,所以,该程序段中 语句①的频度是 n,则程序段的时间复杂度是 T(n)=O(n)。 【例1-5】 分析以下程序的时间复杂度。 for(i=1;i<n;++i) { for(j=0;j<n;++j) { A[i][j]=i*j; ① } } 解:这是二重循环的程序,外层for循环的循环次数是n,内层for循环的循 环次数为n,所以,该程序段中语句①的频度为n*n,则程序段的时间复杂度 为T(n)=O(n2)。 【例1-6】 分析以下程序的时间复杂度。 x=n; /*n>1*/ y=0; while(x >= (y+1)*(y+1)) { y=y+1; ① } 解:这是一重循环的程序,while 循环的循环次数为 n,所以,该程序段 中语句①的频度是 n,则程序段的时间复杂度是 T(n)=O( n)。 【例1-7】 分析以下程序的时间复杂度。 for(i=0;i<m;i++) { for(j=0;j<t;j++) { for(k=0;k<n;k++) { c[i][j]=c[i][j]+a[i][k]*b[k][j]; //① } } } 解:这是三重循环的程序,最外层 for 循环的循环次数为 m,中间层 for 循 环的循环次数为 t,最里层 for 循环的循环次数为 t,所以,该程序段中语 句①的频度是 m*n*t,则程序段的时间复杂度是 T(n)=O(m*n*t)。