《第1章概述》习题解答.docx

上传人:b****8 文档编号:23671872 上传时间:2023-05-19 格式:DOCX 页数:33 大小:132.40KB
下载 相关 举报
《第1章概述》习题解答.docx_第1页
第1页 / 共33页
《第1章概述》习题解答.docx_第2页
第2页 / 共33页
《第1章概述》习题解答.docx_第3页
第3页 / 共33页
《第1章概述》习题解答.docx_第4页
第4页 / 共33页
《第1章概述》习题解答.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

《第1章概述》习题解答.docx

《《第1章概述》习题解答.docx》由会员分享,可在线阅读,更多相关《《第1章概述》习题解答.docx(33页珍藏版)》请在冰豆网上搜索。

《第1章概述》习题解答.docx

《第1章概述》习题解答

第1章概述

本章学习要点

◆了解数据结构的相关概念。

◆了解并掌握数据的4种基本逻辑结构的特点。

◆了解数据的各种基本存储结构。

◆了解算法的相关概念,并能分析各种算法的时间复杂度和空间负责度。

数据结构(DataStructures)是随着计算机科学的发展而逐步形成的一门学科,目前已成为高等院校中计算机类各专业的核心课之一,同时也是统计类、经济类和工程软件设计类各专业的必修课程。

本章的主要内容是对数据结构的基本概念和基本内容作一概要介绍,为此,简单回顾一下数据结构的发展与形成过程对于理解数据结构的内容和重要性是很有必要的。

1.1数据结构的发展概况

众所周知,在40年代计算机刚诞生时,计算机所能处理的数据只能是由0或1组成的二进制数,此时还谈不上什么结构。

后来虽然计算机可以处理十进制整数和十进制实数,也不过是由0到9这十个数字组成的序列,或再加上小数点,其数据的结构非常简单没有研究它的必要。

由于计算机技术的飞速发展和数据处理能力的不断提高,到60年代中期,各种高级程序设计语言相继出现,所能描述的数据类型逐渐丰富。

例如,在FORTRAN语言中允许使用复数类型和数组类型数据。

其中,复数是两个实数的有序对,而数组是同类型数据的一个有限序列,这自然是一种“结构”。

在COBOL语言和PL/1语言中允许使用字符类型和记录类型数据,将计算机的应用领域由数值计算进一步扩充到非数值计算。

其中,记录就是一种“结构”类型的数据,它把一组相互关联的不同类型的数据看作一个整体构成一种新的“结构类型”数据。

有了“结构类型”的概念之后,各个数据之间不再孤立,这样便于表示和储存,也便于处理。

后来,在LISP语言中又定义了一种带有层次性的表结构,并定义了许多相应的运算。

这种层次结构是一种非线性的树型结构,也是本书中将要着重讨论的内容之一。

数据结构作为一门课程的形成和发展主要是在60年代后期。

首先,在1968年由美国计算机协会(ACM)颁发了建议性的计算机教学计划,其中规定数据结构作为一门独立的课程,这在世界上是第一次。

同一年,美国的计算机科学家D.E.Knuth教授在他的巨著《计算机程序设计的技巧》详细论述了数据的逻辑结构和数据的存储结构,并对各种结构给出了典型算法,为数据结构作为一门课程奠定了理论基础。

70年代初,随着大型程序以及大规模文件系统的出现,结构程序设计成为程序设计方法学的主要内容。

在程序设计中,数据结构受到了极大的重视。

认为程序设计的实质就是对要处理的问题选择一种最为适合的数据结构,同时在此结构上施加一种好的算法。

1976年瑞士著名计算机科学家N.Wirth编著的《算法+数据结构=程序》一书正是这种程序设计思想的具体体现。

70年代中后期,由于数据库系统和数据检索系统的不断发展,在数据结构中进一步增加了文件管理的内容以及B-树和B+树的知识,使数据结构的内容得以丰富和进一步完善。

从80年代开始,在我国高等院校的教学计划中已经将数据结构课程列为计算机类各专业的核心课程之一,在许多非计算机专业也把数据结构作为必修课或选修课程。

数据结构是一门介于数学、计算机硬件和计算机软件三者之间的计算机专业基础课,是程序设计方法学、数据库系统、操作系统、编译原理、软件工程学等课程的先修课程,是设计和实现大型应用软件的基础。

1.2数据结构的基本术语和相关概念

数据(data)是能输入到计算机中并能被计算机处理的符号的总称,是计算机程序的加工“原料”。

需要说明的是,这里的“数据”绝对不能狭义地理解为仅仅是数学中的整数或实数而已,必须作广义的理解。

例如,一个有某种功能源程序,一个文件,一张图画,一段声音等等都可以通过编码而归纳为数据的范畴。

数据元素(dataelement)是数据的基本单位,在计算机程序中通常作为一个整体进行处理。

由于数据的范围非常广泛,因此数据元素可大可小,小到一个字符;大到一本书或一张地图等等。

对于较大的数据元素还能进一步分成若干个“数据项(dataitem)”,每个数据项也可以是由几个更小的数据项组成,这样的数据项称为“组合项”,不能再分的数据项称为“原子项”。

例如,一本书的目录信息作为一个数据元素,是由各章的目录组成的,而每章的目录又是由该章中各小节的目录组成。

各章的目录信息就是组合项,如果每一小节的目录不能再分成更小的单位,则称其为原子项,否则称为组合项。

关键字(key)是指数据元素中能够起标识作用的数据项。

其中能够起唯一标识作用的数据项称为“主关键字”,反之称为“次关键字”。

例如,每个学生的信息可以看成是一个数据元素,其中的数据项有:

学号、姓名、性别、年龄和班级等等,由于每个学生都有一个唯一的学号,所以数据项“学号”是主关键字,而姓名可能存在重复所以数据项“姓名”是次关键字。

数据对象(dataobject)是具有相同性质的数据元素的集合,是数据的一个子集。

例如,全体整数的集合N={0,±1,±2,…}就是一个数据对象,全体复数的集合C={|x,y∈R}也是一个数据对象。

在程序设计中,总是针对某个特定的问题处理一种或几种数据对象,不可能在一个问题中处理所有的数据。

例如,在文本编辑系统中的数据对象是文件中所出现的各种文字和符号的集合;在学生成绩管理系统中的数据对象是所有学生的成绩;在电话号码查询系统中的数据对象是全体电话用户的信息所组成的集合。

数据关系(datrelation)是数据对象中各元素之间的一种结构(或序),它反映了数据元素之间存在的一种固有联系。

在数据处理时,通常把一个数据对象中两个元素之间的数据关系简单地用前驱和后继来描述。

例如,某个数据对象中的两个元素a,b之间存在关系:

a是b的前驱(或b是a的后继),则可表示为或a→b。

一周中的7天是一个数据对象,其中的每一天为一个数据元素,它们之间的数据关系有:

,,,,,

数据的逻辑结构(datalogicalstructure)是数据元素之间存在的逻辑(或序)关系的描述,它可以用一个数据元素的集合D,和D中各元素之间存在的所有关系的集合R来表示成DLS=(D,R)。

根据数据之间存在的不同逻辑关系,通常将逻辑结构分为以下4种基本结构:

(1)集合结构(Set)在该逻辑结构中,只有数据元素集D,而关系集为空集合,即R={}。

如图1.1(a)所示的数据对象中,其数据的逻辑结构为集合结构。

(2)线性结构(LineStructure)在该结构中,除了第1个元素(记录)外,其它各元素(记录)都有唯一的直接前驱;除了最后1个元素(记录)外,其它各元素(记录)都有唯一的直接后继。

数据中各元素之间存在一个对一个的关系,如图1.1(b)所示的数据对象中,其数据的逻辑结构为线性结构。

(3)树型结构(TreeStructure)在该结构中,除了一个根元素(结点)外,其它各元素(结点)都有唯一的直接前驱;所有数据元素(结点)都可以有多个后继。

数据中各元素之间存在一个对多个的关系,如图1.1(c)所示的数据对象中,其数据的逻辑结构为树型结构也称为层次结构。

(4)图结构或网结构(GraphStructure)在该结构中,各元素(顶点)之间可以有多个直接前驱和多个直接后继。

数据中各元素之间存在多个对多个的关系,如图1.1(d)所示的数据对象中,其数据的逻辑结构就是图结构。

图结构和树型结构统称为非线性结构。

数据的物理结构(DataPhysicalStructure)又称数据的存储结构,它是数据在计算机中的存储表示,包括数据本身在计算机中的存储方式,以及数据之间的逻辑关系在计算机中的表示。

因此,数据的物理结构是依赖于计算机的。

根据在存储器中表示数据的不同方法,通常有以下4种物理存储结构:

(1)顺序存储结构(SequentialStorageStructure)将逻辑上相邻的数据元素存储在物理位置上相邻的存储单元中,元素之间的逻辑关系由其相应的存储单元的相邻关系来表示。

(2)链式存储结构(LinkedStorageStructure)在存储器中不要求将逻辑上相邻的数据元素存储到相邻的物理存储位置中,而是通过附加指针字段来表示数据元素之间的逻辑关系。

(3)索引存储结构(IndexStorageStructure)在存储数据元素信息的同时,还建立一个附加的索引表,索引表中每一项称为索引项(关键字),它是能够唯一标识一个数据元素的数据项。

(4)哈希存储结构(HashStorageStructure)能根据数据元素的关键字直接算出该数据元素的存储地址。

数据结构(datastructure)是具有结构(或关系)特性的数据元素的集合,它研究的是数据的逻辑结构和物理结构以及它们之间的相互关系,并在这种结构上定义相关的运算,设计并实现相应的算法,分析算法的效率。

数据的逻辑结构和物理结构是数据结构的相互关联的两个方面,同一个逻辑结构可以有几种不同的存储结构。

算法的设计取决于数据的逻辑结构,而算法的实现依赖于数据的存储结构。

1.3应用举例

【例1.1】一周中的7天的数据结构是DLS=(D,R),其中,

D={Sun,Mon,Tue,Wed,Thu,Fri,Sat},

R={,,,,,}。

可用逻辑图形表示该结构为图1.2(a);其顺序存储结构可以表示为图1.2(b);其链式存储结构可以表示成图1.2(c)。

【例1.2】现有下列3种用二元组表示的数据逻辑结构,画出它们对应的逻辑图形表示,并指出它们分别属于何种类型的结构。

(1)A=(K,R),其中:

K={a,b,c,d,e,f,g,h},R={,,,,,,}

(2)B=(K,R),其中:

K={a,b,c,d,e,f,g,h},R={,,,,,,}

(3)C=(K,R),其中:

K={1,2,3,4,5,6},R={(1,2),(2,3),(2,4),(3,4),(3,5),(3,6),(4,5),(4,6)}这里的一对圆括号表示相应的两个结点是双向的。

解:

(1)A对应的逻辑结构图如图1.3(a)所示,它是一种线性结构。

(2)B对应的逻辑结构图如图1.3(b)所示,它是一种树型结构。

(3)C对应的逻辑结构图如图1.3(c)所示,它是一种图结构。

【例1.3】现有如图1.4所示的逻辑结构图示,给出它的逻辑结构。

解:

本题的逻辑结构如下:

DLS=(D,R)其中,D={A,B,C,D,E,F,G,H,I,J},R={r1,r2}

r1={,,,,,,,,}

r2={,,,,,,,}

1.4算法描述和算法分析

如前所述,数据结构必须和研究相应的算法结合起来,才能解决实际中的应用问题。

本节将给出算法的定义和算法的各种描述方法,并进一步从运行的时间开销和空间开销两个方面分析算法执行的效率。

1.4.1算法

算法(Algorithm)是对特定问题求解步骤的一种描述,是为了解决某个问题给出的一个确定的、有限长的操作序列。

一个算法应具有以下5个重要特性:

(1)有穷性一个算法应该包含有限个操作步骤,而不是无限的。

对于合法的输入值,算法能在执行有限次操作之后得到结果。

有限次操作是指操作步骤为有限个,并且每个步骤都能在规定的时间内完成。

(2)确定性算法中的每一个步骤都应当是确定的,而不应当是含糊的、模棱两可的。

并且在同样的条件下,算法只有唯一的一条执行路径,即对于相同的输入只能得出相同的输出。

(3)有零个或有限个输入所谓输入是指在执行算法时需要从外界取得必要的信息或数据。

一个算法可以没有输入也可以有有限个输入,这些输入应来源于某几个特定的数据对象。

(4)有输出结果算法的目的是为了求解,“解”就是输出结果。

一个算法应该有一个或多个输出。

算法的结果可以输出到文件中,也可以打印输出或显示输出,这些输出是与输入的数据有着某种关联的量。

没有输出的算法是无意义的。

(5)可行性一个算法是可行的,即算法中的每一个操作都是可以通过已经实现的基本操作在规定的时间内执行有限次来实现。

1.4.2算法设计要求

在通常情况下,设计算法时应该达到以下4个目标:

(1)正确性算法应该满足具体问题的需求。

即算法应该满足对特定问题进行处理时,在输入、输出、数据加工等方面的要求。

(2)可读性算法除了用于编写程序在计算机上运行之外,另一个重要用处是用于阅读和交流。

可读性好有助于人们对算法的理解,便于对该算法的使用与推广。

(3)健壮性当输入数据非法时,算法也能适当做出反应或进行处理,输出表示错误性质的信息并等待下一次输入或终止程序。

(4)高时间效率和低存储占用量通常情况下,求解同一个问题若有多种算法,则执行时间短的算法效率高,占用存储空间少的算法好。

但是算法的时间开销和空间开销往往是相互制约的,在实际应用中对高时间效率和低存储占用的要求只能根据具体问题折中处理。

1.4.3算法的描述

1.算法的描述方法

根据侧重点的不同对算法的描述方法通常也不一样,常用的方法有如下4种:

(1)自然语言描述法用日常使用的语言,可以是汉语、英语或其他语言,同时还使用一些高级计算机程序设计语言中的语句来描述算法。

其优点是简单、易懂,但文字沉长、容易出现歧义性,且要将一个算法转换成可以上机调试并运行的计算机程序比较困难。

(2)流程图描述法该方法是用一些图框来表示各种操作。

其优点是直观、易懂,但是用来描述比较复杂的算法时其“直观”和“易懂”的优点便不再显现。

同时将流程图转化为可上机运行的程序也不方便。

(3)计算机语言描述法也叫程序法,即使用某一种计算机语言描述出来的算法。

该方法的优点是可以在计算机上直接运行并获得结果。

(4)类计算机语言描述法采用伪码(包括高级语言的3种基本控制结构)和某一种高级语言(比如C或C++语言)相结合的一种“类高级语言”来描述算法的方法。

这种算法只要经过简单的转换即可上机运行。

该方法的优点是易于书写和阅读,能使读者把注意力集中于算法的实质,而不用把精力花在某个高级语言的许多具体约定之上。

2.类C++语言的说明

尽管对数据结构的研究是不依赖于任何计算机程序设计语言的,对于算法可以采用自然语言或流程图来描述。

但是这样描述有时太不精确,难以反映出算法的本质特点,所以还是要选择一种程序设计语言来描述算法。

鉴于目前C++语言最为流行,本书中所有需要精确描述的算法都用“类C++语言”书写。

当然,这种语言书写的程序在语法上不一定十分严格,有些程序还不能直接在计算机上运行,但是在上机时只要根据C++的语法规则对已有的算法经过简单的转换即可。

以下对类C++语言进行简要说明:

(1)元素的类型在数据结构的算法描述中,基本元素的类型约定为ElemType,上机运行时由用户根据需要使用语句“typedef实际类型ElemType;”定义元素的具体类型。

(2)算法(函数)的描述

函数返回类型函数名(函数的形参列表)

{//算法说明部分

//变量的定义和调用函数的声明部分

语句序列

函数返回语句

}

在调用函数时,为了通过被调函数的实参得到运行结果,在函数的形参列表中除了值传递方式外,还使用了C++的引用调用的参数传递方式。

在形参列表中,以&打头的参数即为引用参数,引用参数能通过该函数本身修改主调函数中相应的实参变量的值。

(3)内存的动态分配与释放

动态分配内存语句:

指针变量=new数据类型[元素个数];

释放内存空间语句:

[]delete指针变量;

new和delete是C++语言系统的两个指令而不是函数调用,可以在程序中直接使用该指令。

(4)赋值语句

简单赋值语句:

变量名=表达式;

串联赋值语句:

变量名1=变量名2=…=变量名k=表达式;

结构体变量整体赋值语句:

结构类型变量名={表达式1,表达式2,…,表达式k};

结构体变量名1=结构体变量名2;

条件赋值语句:

变量名=条件表达式?

表达式1:

表达式2;

(5)分支语句

条件语句1:

if(条件表达式)语句;

条件语句2:

if(条件表达式1)语句1;

elseif(条件表达式2)语句2;

……………

elseif(条件表达式k)语句k;

else语句k+1;

swicth语句:

switch(表达式)

{

case常量表达式1:

语句序列1;break;

case常量表达式2:

语句序列2;break;

……………

case常量表达式k:

语句序列k;break;

default:

语句序列k+1;

}

(6)循环语句

for语句:

for(初值表达式序列;条件表达式;循环体表达式2)循环体表达式1;

while语句:

while(条件表达式)循环体表达;

do-while语句:

do{循环体语句序列;}while(条件表达式);

(7)结束语句

continue语句:

结束本次循环进入下次循环的开始。

break语句:

结束循环语句或swicth语句。

return语句:

结束函数运行返回到主调函数。

(8)输入和输出语句

输入语句:

cin>>变量1>>变量2>>…>>变量k;

输出语句:

cout<<表达式1<<…<<表达式n;

在使用输入输出语句之前,要用编译预处理命令#include“iostream.h”将其所在的输入输出流库的头文件包含进来。

(9)逻辑运算符

与运算符--&&,非运算符--!

,或运算符--||。

(10)注释语句

单行注释:

//文字注释序列

多行注释:

/*注释文字开始…………注释文字结束*/

【例1.4】现有n(n>1)个不同值的数据元素a[0],a[1],…,a[n-1],求它们中的最大值max和最小值min。

方法1用自然语言描述其算法如下:

①将a[0]、a[1]中的较小者赋值给min,较大者赋值给max;

②把2赋值给k;

③当k

④如果a[k]

⑤如果a[k]>max则,max<=a[k];

⑥使k<=k+1;

⑦转移到语句③去执行;

⑧返回最小数min和最大数max。

方法2用流程图描述算法如图1.5所示。

方法3用C++语言描述的算法如下:

voidfunction(intA[],intn,int&min,int&max)//functionbegin

{//求n个整型数据元素A[0],A[1],…,A[n-1]中的最小元素到min最大元素到max中。

intk;

if(A[0]

else{min=A[1];max=A[0];}

for(k=2;k

if(A[k]

elseif(A[k]>max)max=A[k];

}//functionend

方法4用类C++语言描述的算法如下:

voidfunction(ElemTypeA[],intn,ElemType&min,ElemType&max)//begin

{//求n个元素A[0],A[1],…,A[n-1]中的最小元素到min最大元素到max中。

intk;

if(A[0]

else{min=A[1];max=A[0];}

for(k=2;k

if(A[k]

elseif(A[k]>max)max=A[k];

}//end

1.4.4算法效率的分析

对于同一个问题(例如对n个整数进行排序)可以有许多不同的算法,那么该怎样判断算法的优劣呢?

一个算,法除了它的正确性必须保证以外,主要的一个指标是它的效率。

算法效率包括时间与空间两个方面,分别称为时间复杂度与空间复杂度。

算法分析的目的是根据实际问题,从多种算法中选取一个最为适合的算法并从时间效率和空间效率两方面给出评价。

1.算法的时间复杂度

时间复杂度是指一个算法所需运算次数的多少。

时间复杂度不是表示为一个绝对的量,而是表示为算法中基本操作的执行次数随着问题规模(即数据元素的个数通常用整数n表示)的增长而增长的趋势。

在求算法的时间复杂度时主要考虑该算法中的基本操作重复执行的次数与问题规模

的函数关系

如果随着问题规模

的增大,算法执行次数的增长率与

的增长率相同,则算法的时间复杂度记作

其中,

为问题的规模即数据元素的个数,

为基本操作的执行次数也叫频度。

【例1.5】分析以下程序段的时间复杂度。

for(i=0;i<=n;i++)

{y=y+1;

for(j=0;j<=2*n;j++)x++;

}

该算法的规模为n,基本操作是语句“x++;”,它在内层循环中的执行次数为2n+1次,外层循环的执行次数为n+1次。

基本操作的频度为

时间复杂度为

【例1.6】分析以下程序段的时间复杂度。

i=s=0;

while(s

该算法的规模为

,基本操作是语句“

”,该语句在循环中的执行次数为

次。

结束循环时有关系式:

成立(其中c为常数),即

所以算法的时间复杂度为:

【例1.7】分析以下程序段的时间复杂度。

i=1;while(i<=m)i=i*3;

该算法的规模为

,基本操作是语句“

”,它在循环中的执行次数为

次。

退出循环时有关系式:

成立(其中c为常数),即:

时间复杂度为:

需要说明的是:

(1)一个算法中基本操作的频度的精确值有时不易求得,此时只需要求出它关于规模n的增长率或增长的阶数即可(例题1.6、例题1.7)。

(2)有些情况下,算法中基本操作重复执行的次数还与问题的输入数据有关,此时我们所讨论问题的时间复杂度是在最坏情况下的时间复杂度。

2.算法的空间复杂度

一个算法处理需要存储空间来寄存程序本身所用到的指令、常量、变量和输入输出数据外,也需要一些对数据进行操作的工作单元即为辅助空间。

空间复杂度是指一个算法所需的辅助内存空间的大小。

假如随着问题规模

的增大,算法运行时所需要的辅助存储空间是

的函数

,且

增加时

的增长率与辅助空间的增长率相同,空间复杂度记为:

其中,

为问题的规模,

为辅助空间的大小。

1.5习题

一、简答题

1.举例说明什么叫数据、数据元素、数据项和数据结构?

2.数据结构研究的主要问题是什么?

3.算法分析的目的是什么?

算法分析的两个主要方面是什么?

二、填空题

1.数据的逻辑结构被形式地定义为(D,R),期中D是()的有限集,R是D上()的有限集。

2.数据结构在计算机内存中的表示是指数据的()结构。

3.数据逻辑结构的基本类型除了集合结构类型外还有()、()和(),其中()是非线性结构。

4.线性结构中元素之间存在()关系,树型结构中元素之间存在()关系,图型结构中元素之间存在()关系。

三、解答题

1.设数据的逻辑结构为:

B

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 历史学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1