1.1 知识点分析
1.数据
数据是信息的载体,是对客观事物的符号表示。数据是计算机化的现实世界的事物的抽象描述。凡是能被计算机识别、存取和加工处理的符号、字符、图形、图象、声音、视频信号等一切信息都可以称为数据。 2.数据元素
数据元素是对现实世界中某独立个体的数据描述,是数据的基本单位。数据元素也称为结点,通常由若干数据元素组成。 3.数据项
数据项是数据不可分割的、具有独立意义的最小数据单位,是对数据元素属性的描述。 数据、数据元素、数据项反映了数据组织的三个层次,即数据可以由若干个数据元素组成,数据元素又有若干数据项组成。 4.数据对象
数据对象是性质相同的数据元素的集合,是数据的一个子集。 5.数据结构
数据结构是相互之间存在的一种或多种特定关系的数据元素的集合。简言之,数据结构是指数据之间的关系,即数据的组织形式。数据结构包括以下三个方面: (1)数据的逻辑结构
指数据元素之间的逻辑关系,即从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。一个数据的逻辑结构G可以用二元组G=(D,R)来表示,其中D是数据元素的集合,R是D上所有数据元素之间关系的有限集合。
线性结构是指数据元素之间存在“一对一”关系的逻辑结构,非线性结构是指数据元素之间存在“一对多”或“多对多”关系的逻辑结构。 (2)数据的存储结构
数据元素及其关系在计算机存储器内的表示,称为数据的存储结构,也称为数据的物理结构。数据的存储结构是数据的逻辑结构用计算机语言的实现,它依赖于计算机语言。 (3)数据的运算
指对数据施加的操作。数据的运算是定义在数据的逻辑结构上的,而运算的实现则是在存储结构上进行的。 6.算法的描述和分析
数据的运算是通过算法来描述的,对于算法的说明可以使用不同的语言,对同一问题可以有不同的算法。首选选用的算法必须是正确的。其次,主要考虑执行算法所耗费的时间(即时间效率)和执行算法所耗费的存储空间(即空间效率)。 (1)时间复杂度
通常把算法中所包含简单操作次数的多少叫做算法的时间复杂度。但是当一个算法比较复杂时,其时间复杂度的计算会变得相当困难。一般情况下,算法中原操作重复执行的次数是规模n的某个函数f(n),算法的时间复杂度T(n)的数量级可记作:T(n)=O(f(n))。
算法的时间复杂度T(n)是该算法的时间消耗,一个算法的时间耗费就是该算法中所有语句的执行次数(频度)之和。当n→∞时(即当n相当大时),用大“O”,T(n)的数量级(阶)记号表示。由于limT(n)/f(n)=C,C是不为0的常数,所以T(n)=O(f(n))。其实,f(n)就是T(n)中最高阶的那一项,是算法中频度最大的语句频度。
一般情况下,对于循环语句只需要考虑循环体中语句的执行次数,而忽略该语句中循环
1
头的部分。有时,循环体中语句的频度不仅与问题规模n有关,还与输入实例等其它因素有关,此时可以用最坏情况下的时间复杂度作为算法的时间复杂度。 (2)空间复杂度
一个程序的空间复杂度是指程序运行从开始到结束所需要的存储空间。类似于算法的时间复杂度,我们把算法所需存储空间的量度,记作:S(n)=O(f(n))。其中n为问题的规模。一个程序上机执行时,除了需要存储空间来存放本身所用的指令、常数、变量和输入数据以外,还需要一些对数据进行操作的工作单元和实现算法所必需的辅助空间。在进行时间复杂度分析时,如果所占空间量依赖于特定的输入,一般都按最坏情况来分析。
程序运行时所需要的存储空间包括以下两个部分:
固定部分:主要包括程序代码、常量、变量、结构体变量等所占的空间。空间与所处理的数据大小和个数无关,或者说与问题事例的特征无关。
可变部分:空间大小与算法在某次执行中处理的特定数据的大小和规模有关。
1.2 典型习题分析
【例1】 算法与程序的区别
分析:算法与程序的既有区别,又有联系。其区别是:
(1)算法必须满足有穷性,而程序则不一定满足有穷性。例如,我们启动计算机必须使用操作系统,只要不关机或不遭受破坏,操作系统就永不终止。即使没有作业运行,它也一直处在一个等待循环之中。因此,操作系统是一个不终止的计算过程,但它不满足算法的定义。 (2)程序中的指令必须用计算机可以接受的语言书写,而算法则无此限制。但是,当用一个计算机可以接受的语言来书写算法时,它就是程序。一般而言,算法比较抽象,而程序则比较具体。
【例2】 通常一个算法的时间复杂度是指( )。
A.算法的平均时间复杂度 B.算法在最坏情况下的时间复杂度 C.算法的期望运行时间 D.算法在最好情况下的时间复杂度 分析:如果没有“平均”、“最好”、“最坏”的修饰语,时间复杂度就是指最坏的时间复杂度。最坏时间复杂度是算法的所有输入可能情况的执行时间的上界,所以应选B。 【例3】当n从1变化到10时,比较n、2n、n2、n3、2n、n!、nn增长率的变化。
解:表1-1给出当n从1变化到10时的各函数变化过程,可见当n>=10时,按增长率由小到大排列次序依次为:n、2n、n2、n3、2n、n!、nn。
表1-1 各函数值增长表
n 1 2 3 4 5 6 7 8 9 10 sin n2n 2 4 6 8 10 12 14 16 18 20 n2 1 4 9 16 25 36 49 64 81 100 n3 1 8 27 64 125 216 343 512 792 1000 2n 2 4 8 16 32 64 128 256 512 1024 n! 1 2 6 24 120 720 5040 40320 362880 3628800 nn 1 4 27 256 3125 46656 823543 16777216 3.9╳108 1.0╳1010 【例4】 T(n)=n,则用大“O”记号可以表示为( )。
-1
A.T(n)= O (n) B.T(n)= O (1)
2
C.T(n)= O (n) D.不确定
分析:sin n的取值范围是-1到1之间,所以T(n)的上界为O(n1),即O(n),所以应选C。
【例5】设两个算法的执行时间分别为100n2和2,它们在同一台计算机上运行,要使前者快于后者,n至少要多大?
nn
分析:要使前者快于后者,即要求满足100n2<2 的n。由于100n2和2 这两个函数都是单
n
调增加函数,随着n的增大,2的递增速度比100n2快。在n>=1的整数情况下,可测出当
n
n>=15时,100n2<2 (可以编一个程序进行测试)。所以要使前者快于后者,n至少要大于等于15。
【例6】 当n充分大时,按从小到大的次序对下列时间排序: (1) T1(n)=5n2+10n+6lgn (2) T2(n)=3n2+100n+3lgn (3) T3(n)=8n2+3lgn (4) T4(n)=2n2+6000nlgn
分析:为了比较两个同数量级算法的优劣,需突出主项的常数因子,而将低次的项用大“O”的记号进行表示。则T1(n)=5n2+10n+6lgn=5n2+O(n),T2(n)=3n2+100n+3lgn=3n2+O(n),T3(n)=8n2+3lgn= 8n2+O(lgn),T4(n)=2n2+6000nlgn=2n2+O(nlgn)。当n足够大时,T1(n) 、T2(n)、T3(n)、T4(n)的时间复杂度都为O(n2),虽然它们的数量级相同,但他们主项的系数还是有区别。因为T4(n)主项常数因子< T2(n) 主项常数因子< T1(n) 主项常数因子< T3(n) 主项常数因子,所以从优到劣的顺序为:T4(n) 、T2(n)、T1(n)、T3(n)。 【例7】 设三个函数f、g、h分别为:f(n)=100n3+n2+100、g(n)=25n3+50n2、h(n)=n1.5+50nlgn,请判断下列关系是否成立:
(1)f(n)=O (g(n)) (2)h(n)=O (n1.5) (3)h(n)=O (nlgn) 分析:
(1)lim f(n)/g(n)=lim(100n3+n2+100)/(25n3+50n2)=4,即f(n)和g(n)的数量级相同。 所以(1)f(n)= O (g(n)) 成立。
(2)h(n)的数量级取决于n1.5和nlgn,50是与n无关的常数因子,可以忽略。因为n1.5 的数量级大于lgn,也大于nlgn,即lim h(n)/n1.5=lim (n1.5+50nlgn)/n1.5=1,所以(2)h(n)=O (n1.5)成立。
(3)lim h(n)/nlgn=lim(n1.5+50nlgn)/nlgn=∞,所以(3)h(n)=O (nlgn)不成立。
【例8】 将一维数组中的元素逆置的算法如下,试分析其时间频度及时间复杂度。 void exchange (int a[],int n) {
fot (int i=0; i<=n/2-1;i++)
{
int t=a[i]; a[i]=a[n-i-1];
a[n-i-1]=t; }
}
答:时间频度为T(n)=3n/2,当n充分大时,n的系数3/2可以忽略不计,所以其时间复杂度为O(n)。
【例9】 将n个元素按升序排列的算法如下,试分析其时间频度及时间复杂度。 void sort(int a[],int n)
3
n
{
int i,j,k,t;
fot (i=0;i for (j=i+1;j<=n-1;j++) if (a[k]>a[j]) k=j; if (k!=i) {t=a[k];a[k]=a[i];a[i]=t;} } } 答:时间频度为T(n)=1+ (n-1) + (1+2+3+…+n-1)+3(n-1)=n2/2+7n/2-3,时间复杂度为O(n2)。 【例10】 设n为正整数,分析下列程序段中加下划线的语句的程序步数。 int i=1; do{ fot (int j=1;j<=n;j++) i=i+j ; }while (i<100+n) 分析:i=1结束时,i=1+n(n+1)/2 i=2结束时,i=(1+n(n+1)/2)+n(n+1)/2=1+2(n(n+1)/2) i=3结束时,i=(1+2(n(n+1)/2))+n(n+1)/2=1+3(n(n+1)/2) 一般地,i=k结束时,i=1+k(n(n+1)/2)<100+n, 求出满足此不等式的k的最大值,语句i=i+j的程序步数为:(k+1)*(n(n+1)/2) 1.3 单元练习1解答 一.判断题答案 题目 答案 二.填空题答案 (1) (3) (5) (7) (9) 存储结构 1 1 √ 2 × 3 × 4 × 5 × 6 √ 7 √ 8 √ 9 × 10 √ (2)图形结构 (4)树形结构 图形结构 (6)任意多个 (8)散列存储 (10)一对多 (12)算法(或运算) (14)有穷指令 (16)输入规模 (18)O(nlog2n) (20)操作对象 非线性结构 物理结构 一对一 (11) 多对多 (13) 关系 (15) 事后统计法 (17) 存储空间 (19) O(n2) 三.选择题答案 4 题目 1 2 3 4 5 6 7 8 9 10 答案 A C C D A C B A B D 题目 11 12 13 14 15 16 17 18 19 20 答案 C A A C A C D D A C 四.答案 (1) O(n*m) (2) O(n2) (3) O(1) (4) O(n) (5) O(n2) 五.答案 (1) a b c d e 属于集合 (2) a b c d e f 属于线性结构 (3) 50 25 64 36 57 82 55 75 属于树结构 (4) 1 2 3 4 5 6 属于图结构 (5) 5 d b g a c e h f 属于树结构。 6 因篇幅问题不能全部显示,请点此查看更多更全内容