1 数据结构的基本概念
1.1数据结构研究的对象
(1)数据的逻辑结构
(2)数据的物理存储结构
(3)对数据的操作(算法):算法的设计取决于数据的逻辑结构,实现取决于数据的物理存储结构。
计算机解决实际问题步骤:首先得到实际问题的数学模型(模型误差),然后设计相应的算法,最后编程实现,调试、完善,直至问题的解决。问题不变:线性方程,动态问题:微分方程。
例1.求一组整数的最大值。算法:基本操作为"比较两个数的大小";模型:一个线性序列,线性结构。
例2.计算机对弈。算法:对弈的规则和策略;模型:层次结构的树型结构
1.2 数据结构的基本术语
(1)数据结构:是相互存在一种或多种特定关系的数据元素的集合;
(2)逻辑结构:数据元素之间的相互逻辑关系,与数据的存储无关,是独立计算机的;
(3)物理结构(存储结构):数据在计算机中表示映射(存储)。具体的实现方法有顺序、链接、索引、散列等,一种数据结构可以表示成一种或多种存储结构。
1.3 四种基本的逻辑结构
(1)集合:数据结构中的数据元素除了"同属一个数据集合"的相互关系,不存在其他关系。
(2)线性关系:数据结构中的数据元素之间存在一对一的相互关系。
(3)树形结构:数据结构中的数据元素之间存在一对多的相互关系。
(4)图形结构:数据结构中的数据元素之间存在多对多的相互关系。
1.4 顺序存储和链式存储
数据元素之间关系的计算机内表示可分为顺序映射和非顺序映射,常用的两种存储结构:顺序存储结构和链式存储结构。顺序存储结构借助元素在存储器中的相对位置来表示数据之间的逻辑关系;非顺序结构像借助指示元素存储位置的指针(Pointer)来表示数据元素之间的逻辑关系。
例1:序列A=(12,23,44,33,65)的两种存储结构。
顺序存储结构:首元素12存放的地址为0100,占两个字节,第二个元素存放地址为0102,占两个字节,依次类推。
链式存储结构:首元素12存放地址为0108,第二个元素的存储位置由首元素的指针指示出来,地址为0104,;第三个元素的存储位置由第二个元素指针指出。依次类推。最后元素的指针为空。
2 算法与数据结构
2.1 算法
计算机科学家N.Wirth提出一个公式:算法 + 数据结构 = 程序,揭示了算法与数据结构的重要性和统一性。
算法:对特定问题求解步骤的一种描述,它是指令的有限序列,其中每一条指令表示一个或者多个操作。
算法的五个重要特性:有穷性、确定性、可行性、输入、输出。
算法与程序的含义十分相似,但是又有区别。一个程序不一定满足有穷性,例如操作系统。另外,程序指令必须是可执行的,算法中的指令没有此限制。
由于数据逻辑结构和数据物理结构不是唯一的,很大程度由用户设计和选择,所以处理一个问题的算法不是唯一的。对于相同的逻辑结构和物理结构。算法设计的思想和技巧也不同。
学习数据结构的目的就是为了根据问题的需要,为处理的数据选择合适的逻辑结构和物理结构,进而设计出比较满意的算法。
2.2 算法分析
设计算法时,通常需要考虑以下目标:
(1)正确性:算法应该能够正确的实现预定的功能。
(2)可读性:易于阅读和理解,以便调试、修改和补充。
(3)健壮性:当输入非法时,算法能够适当的做出反应或处理,而不会产生莫名其妙的结果。
(4)高效性:执行时间,存储空间。
时间复杂度:算法中包含简单操作的次数,是一个算法运行时间的相对度量。
算法的时间复杂度可看成是问题规模的函数,T(n),例如下面累加求和运算。
1 int sum(int a[],int n){ 2 int s,i; //1次 3 s = 0; //1次 4 i = 0; //1次 5 while(i < n){ //n+1次 6 s += a[i]; //n次 7 i ++; //n次 8 } 9 return s; //1次 10 } 11 //时间复杂度 :T(n)=3n+4
当算法比较复杂时,时间复杂度计算相当困难,但是一般没有必要精确的计算算法的时间复杂度,只要大致计算出相应的数量级O(f(n))。
算法的时间复杂度采用数量级的形式表示后,将给求解算法的T(n)带来很大方便,一般只要分析循环体内简单操作的执行次数,
估计算法复杂度的常用方法:
(1)多数情况下,求最深循环内的简单语句的重复操作次数;
(2)当难以精确计算原操作执行的次数时,只需要求出它关于n的增长率或阶;
(3)当循环次数未知,求最坏情况下的简单语句的重复次数。
例如:单层for的时间复杂度表示为O(n),双层for的为O(n2)。
多项式时间算法的关系:O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3)
指数时间算法的关系:O(2n) < O(n!) < O(nn)
空间复杂度:算法存储空间的度量,S(n) = O(g(n)),表示随着问题规模n的增大,算法运行所需存储空间的增长与g(n)相同。
算法的存储量包括:(1)输入数据所占空间;(2)程序本身的所占空间;(3)辅助变量的所占空间
由于输入数据所占空间只取决于问题本身,和算法无关,所以只需要分析除输入和程序之外的额外空间。