一、绪论
(一)基本概念
数据:数据是对客观事物的符号表示,在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。
数据元素:数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。一个数据元素可由若干个数据项组成,数据项是构成数据元素的不可分割的最小单位。
数据对象:数据对象是性质相同的数据元素的集合,是数据的一个子集。
数据结构:数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
数据元素都不是孤立存在的,而是在它们之间存在着某种关系,这种数据元素相互之间的关系称为结构。
数据结构三要素:
1、逻辑结构
结构定义中的“关系”描述的是数据元素之间的逻辑关系,因此又称为数据的逻辑结构
根据数据元素之间关系的不同特性,通常有下列4类基本结构:
-
集合:结构中的数据元素之间除了“同属于一个集合”的关系外,别无其他关系。
-
线性结构:结构中的数据元素之间存在一个对一个的关系。除了第一个元素,所有元素都有唯一的前驱;除了最后一个元素,所有元素都有唯一后继。
-
树形结构:结构中的数据元素之间存在一个对多个的关系
-
图状结构或网状结构:结构中的数据元素之间存在多个对多个的关系
2、数据的运算
针对于某种逻辑结构,结合实际需求,定义基本运算。
3、物理结构(存储结构)
数据结构在计算机中的表示称为数据的物理结构,又称为存储结构。
数据元素之间的关系在计算机中有两种不同的表达式:顺序映射和非顺序映射,并由此得到两种不同的存储结构:顺序存储结构和链式存储结构。
顺序映射:特点是接触元素在存储器中的相对位置来表示数据元素之间的逻辑关系。
非顺序映射:特点是借助指示元素存储地址的指针表示数据元素之间的逻辑关系。
(1)顺序存储
把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。
(2)链式存储
逻辑上相邻的元素在物理位置上可以不相邻,借助指示元素存储地址的指针来表示元素之间的逻辑关系。
(3)索引存储
在存储元素信息的同时,还建立附加的索引表。索引表中的每项称为索引项,索引项的一般形式是(关键字,地址)
(4)散列存储
根据元素的关键字直接计算出该元素的存储地址,又称哈希(Hash)存储。
4、总结
(1)若采用顺序存储,则各个数据元素在物理上必须是连续的;若采用非顺序存储,则各个数据元素在物理上可以是离散的。
(2)数据的存储结构会影响存储空间分配的方便程度
(3)数据的存储结构会影响对数据运算的速度
运算的定义是针对逻辑结构的,指出运算的功能;
运算的实现是针对存储结构的,指出运算的具体操作步骤。
数据类型和抽象数据类型
数据类型
数据类型是一个值的集合和定义在此集合上的一组操作的总称。
-
原子类型。其值不可再分的数据类型。
-
结构类型。其值是由若干个成分按某种结构组成的,因此是可以再分解的,并且它的成分可以是非结构的也可以是结构的。
抽象数据类型(Abstract Data Type,ADT)
抽象数据组织及与之相关的操作。
抽象数据类型的定义由一个值域和定义在该值域上的一组操作组成。若按照其值的不同特性可以分为3种:
-
原子类型:原子类型的变量的值是不可分解的。这类抽象数据类型较少,因为一般情况下,已有的固有数据类型足以满足需求。
-
固定聚合类型:该类型的变量,其值由确定数目的成分按某种结构组成。
-
可变聚合类型:和固定聚合类型相比较,构成可变聚合类型“值”的成分的数目不确定。
显然,后两种类型可统称为结构类型。
(二)算法和算法分析
1、算法
算法是对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或多个操作。一个算法还具有下列5个重要特性:
(1)有穷性:一个算法必须总是(对任何合法的输入值)在执行有穷步之后结束,且每一步都可在又穷时间内完成。
(2)确定性:算法中每一条指令必须有确切的含义,读者理解时不会产生二义性。并且在任何条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。
(3)可行性:一个算法是能行的,即算法中描述的操作都是可以通过已经实现的基本运算执行有限次来实现的。
(4)输入:一个算法有零个或多个的输入,这些输入取自于某个特定的对象的集合。
(5)输出:一个算法有一个或多个的输出,这些输出是同输入有着某些特定关系的量。
2、算法设计要求
通常设计一个“好”的算法应考虑达到以下目标:
(1)正确性:算法应当满足具体问题的需求。
(2)可读性:算法应具有良好的可读性,以帮助人们理解。
(3)健壮性:输入非法数据时,算法能适当地做出反应或进行处理,而不会产生莫名其妙的输出结果。
(4)效率与低存储量需求:效率指的是算法执行的时间。存储量需求值算法执行过程中所需要的最大存储空间。
3、算法效率的度量
算法执行时间需通过依据该算法编制的程序在计算机上运行时所消耗的时间来度量。而度量一个程序的执行时间通常有两种方法:
(1)事后统计的方法
(2)事前分析估算的方法
一般情况下,算法中基本操作重复执行的次数是问题规模n的某个函数f(n),算法的时间度量记作:
它表示随问题规模n的增大,算法执行时间的增长率和f(n) 的增长率相同,称做算法的渐近时间复杂度,简称时间复杂度。
结论一:顺序执行的代码只会影响常数项,可以忽略。
结论二:只需挑循环中的一个基本操作分析它的执行次数与n的关系即可。
结论三:如果有多层嵌套循环,只需关注最深层循环了几次。
4、算法的存储空间需求
空间复杂度:空间开销(内存开销)与问题规模n之间的关系。
以空间复杂度作为算法所需存储空间的亮度,记作: