1、 数据结构( C语言版)(第 2版) 课后习题答案 李冬梅 2015.3 II 目录 第 1 章绪论 . 1 第 2 章线性表 . 5 第 3 章栈和队列 . 13 第 4 章串、数组和广义表 . 26 第 5 章树和二叉树 . 33 第 6 章图 . 42 第 7 章查找 . 54 第 8 章排序 . 65 1 第 1 章绪论 1简述下列概念: 数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构 、抽象数据类型。 答案: 数据 :是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、
2、图像、声音、动画等通过特殊编码定义后的数据。 数据元素 :是数据 的基本单位,在计算机中通常作为一个整体进行考虑和处理。在有些情况下,数据元素也称为元素、结点、记录等。数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。 数据项 :是组成数据元素的、有独立含义的、不可分割的最小单位。例如,学生基本信息表中的学号、姓名、性别等都是数据项。 数据对象 : 是性质相同的数据元素的集合,是数据的一个子集。例如:整数数据对象是集合 N=0, 1, 2, ,字母字符数据对象是集合 C=A , B , Z , a , b , z ,学 生基本信息表也可是一个数据对象
3、。 数据结构 : 是相互之间存在一种或多种特定关系的数据元素的集合。换句话说,数据结构是带“结构”的数据元素的集合,“结构”就是指数据元素之间存在的关系。 逻辑结构 :从逻辑关系上描述数据,它与数据的存储无关,是独立于计算机的。因此,数据的逻辑结构可以看作是从具体问题抽象出来的数学模型。 存储结构: 数据对象在计算机中的存储表示,也称为 物理结构 。 抽象数据类型 : 由用户定义的,表示应用问题的数学模型,以及定义在这个模型上的一组操作的总称。具体包括三部分:数据对象、数据对象上关系的集合和对数据对象的基本操作的集合。 2试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
4、 答案: 例如有一张学生基本信息表,包括学生的学号、姓名、性别、籍贯、专业等。每个学生基本信息记录对应一个数据元素,学生记录按顺序号排列,形成了学生基本信息记录的线性序列。对于整个表来说,只有一个开始结点 (它的前面无记录 )和一个终端结点 (它的后面无记录 ),其他的结点则各有一个也只有 一个直接前趋和直接后继。学生记录之间的这种关系就确定了学生表的逻辑结构,即线性结构。 这些学生记录在计算机中的存储表示就是存储结构。如果用连续的存储单元 (如用数组表示 )来存放这些记录,则称为顺序存储结构;如果存储单元不连续,而是随机存放各个记录,然后用指针进行链接,则称为链式存储结构。 即相同的逻辑结构
5、,可以对应不同的存储结构。 3简述 逻辑结构的四种基本关系并画出它们的关系图。 2 答案: ( 1) 集合结构 数据元素之间除了“属于同一集合”的关系外,别无其他关系。例如,确定一名学生是否为班级成员,只需将班级看做一个集合结构。 ( 2) 线性结构 数据元素之间存在一对一的关系。例如,将学生信息数据按照其入学报到的时间先后顺序进行排列,将组成一个线性结构。 ( 3) 树结构 数据元素之间存在一对多的关系。例如,在班级的管理体系中,班长管理多个组长,每位组长管理多名组员,从而构成树形结构。 ( 4) 图结构或网状结构 数据元素之间存在多对多的关系。例如,多位同学之间的朋友关系,任何两位同学都可
6、以是朋友,从而构成图形结构或网状结构。 其中树结构和图结构都属于非线性结构。 4 存储结构由哪两种基本的存储方法实现? 答案: ( 1)顺序存储结构 顺序存储结构是借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系,通常借助程序设计语言的数组类型来描述。 ( 2)链式存储结构 顺序存储结构要求所有的元素依次存放在一片连续的存储空间中,而链式存储结构,无需占用一整块存储空间。但为了表示结点之间的关系,需要给每个结点附加指针字段,用于存放后继元素的存储地址。所以链式存储结构通常借助于程序设计语言的指针类型来描述。 5 选择题 ( 1)在数据结构中,从逻辑上可以把数据结构分成( )。 A 动态
7、结构和静态结构 B 紧凑结构和非紧凑结构 四类基本逻辑结构关系图 3 C线性结构和非线性结构 D 内部结构和外部结构 答案: C ( 2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的( )。 A 存储结构 B 存储实现 C 逻辑结构 D 运算实现 答案: C ( 3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着( )。 A 数据具有同一特点 B不仅数据元 素所包含的数据项的个数要相同,而且对应数据项的类型要一致 C 每个数据元素都一样 D 数据元素所包含的数据项的个数要相等 答案: B ( 4)以下说法正确的是( )。 A 数据元素是数据的最小单位 B 数据项是数据
8、的基本单位 C 数据结构是带有结构的各数据项的集合 D一些表面上很不相同的数据可以有相同的逻辑结构 答案: D 解释:数据元素是数据的基本单位,数据项是数据的最小单位,数据结构是带有结构的各数据元素的集合。 ( 5)算法的时间复杂度取决于( )。 A问题的规模 B待处理数据的初态 C计算机的配置 D A 和 B 答案: D 解释: 算法的时间复杂度不仅与问题的规模有关,还与问题的其他因素有关。如某些排序的算法,其执行时间与待排序记录的初始状态有关。为此,有时会对算法有最好、最坏以及平均时间复杂度的评价。 ( 6)以下数据结构中,()是非线性数据结构 A树 B字符串 C队列 D栈 答案: A 6
9、试 分析下面各程序段的时间复杂度。 ( 1) x=90; y=100; while(y0) if(x100) x=x-10;y-; else x+; 答案: O(1) 解释:程序的执行次数为常数阶。 4 ( 2) for (i=0; i1 y=0; while(x (y+1)* (y+1) y+; 答案: O( n ) 解释:语句 y+;的执行次数为 n 。 5 第 2 章线性表 1 选择题 ( 1) 顺序表中第一个元素的存储地址是 100,每个元素的长度为 2,则第 5 个元素的地址是 ()。 A 110 B 108 C 100 D 120 答案: B 解释: 顺序表中的数据 连续存储, 所
10、以第 5 个元素的地址为: 100+2*4=108。 ( 2) 在 n 个结点的顺序表中,算法的时间复杂度是 O(1)的操作是 ()。 A 访问第 i 个结点( 1 i n)和求第 i 个结点的直接前驱( 2 i n) B 在第 i 个结点后插入一个新结点( 1 i n) C 删除第 i 个结点( 1 i n) D 将 n 个结点从小到大排序 答案: A 解释: 在顺序表中插入一个结点的时间复杂度都是 O(n2 ),排序的时间复杂度为 O(n2 )或 O(nlog2n)。顺序表是一种随机存取结构,访问第 i 个结点和求第 i 个结点的直接前驱都可以直接通过数组的下标直接定位,时间复杂度是 O(
11、1)。 ( 3) 向一个有 127 个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动的 元素 个数为 ()。 A 8 B 63.5 C 63 D 7 答案: B 解释:平均要移动的元素个数为: n/2。 ( 4) 链接存储的存储结构所占存储空间 ()。 A 分两部 分,一部分存放结点值,另一部分存放表示结点间关系的指针 B 只有一部分,存放结点值 C 只有一部分,存储表示结点间关系的指针 D 分两部分,一部分存放结点值,另一部分存放结点所占单元数 答案: A ( 5) 线性表若采用链式存储结构时,要求内存中可用存储单元的地址 ()。 A 必须是连续的 B 部分地址必须是连续的 C
12、一定是不连续的 D 连 续或不连续都可以 答案: D ( 6) 线性表在 () 情况下适用于使用链式结构实现。 A 需经常修改中的结点值 需不断对进行删除插入 C 中含有大量的结点 中结点结构复杂 答案: B 6 解释:链表最大的优点在于插入和删除时不需要移动数据,直接修改指针即可。 ( 7) 单链表的存储密度 ()。 A 大于 1 B 等于 1 C 小于 1 D 不能确定 答案: C 解释: 存储密度是指一个结点数据 本身 所占的存储 空间 和整个结点所占的存储 空间 之比 ,假设单链表一个结点本身 所占的 空间为 D,指针域所占的空间为 N,则存储密度为: D/(D+N),一定小于 1。
13、( 8)将两个各有 n 个元素的有序表归并成一个有序表,其最少的比较次数是()。 A n B 2n-1 C 2n D n-1 答案: A 解释:当 第一个有序表中所有的元素都小于 (或 大于 ) 第二个 表中的元素,只需要用第二个表中的第一个元素依次与第一个表的元素比较,总计比较 n 次 。 ( 9) 在一个长度为 n 的顺序表中,在第 i 个元素( 1 i n+1)之前插入一个新元素时须向后移动()个元素。 A n-i B n-i+1 C n-i-1 D I 答案: B (10) 线性表 L=(a1, a2 , an ),下列说法正确的是()。 A每个元素都有一个直接前驱和一个直接后继 B线
14、性表中至少有一个元素 C表中诸元素的排列必须是由小到大或由大到小 D除第 一个和最后一个元素外,其余每个元素都有一个且仅有一个直接前驱和直接后继。 答案: D (11) 创建一个包括 n 个结点的有序单链表的时间复杂度是()。 A O(1) B O(n) C O(n2 ) D O(nlog2n) 答案: C 解释:单链表创建的时间复杂度是 O(n),而要建立一个有序的单链表,则每生成一个新结点时需要和已有的结点进行比较,确定合适的插入位置,所以时间复杂度是O(n2)。 (12) 以下说法错误的是()。 A求表长、定位这两种运算在采用顺序存储结构时实现的效率不比采用链式存储结构时实现的效率低 B
15、顺序存储的线性表可以随机存取 C由于顺序存储要求连续的存储区域,所以在存储管理上不够灵活 D线性 表的链式存储结构优于顺序存储结构 答案: D 解释: 链式存储结构和顺序存储结构各有优缺点,有不同的适用场合。 (13) 在单链表中,要将 s 所指结点插入到 p 所指结点之后,其语句应为()。 7 A s-next=p+1;p -next=s; B (*p).next=s;(*s ).next=(*p).next; C s-next=p -next;p-next=s-next; D s-next=p-next;p -next=s; 答案: D (14) 在双向链表存储结构中,删除 p 所指的结点
16、时须修改指针()。 A p-next -prior=p -prior;p-prior-next=p-next; B p-next=p-next-next;p -next-prior=p; C p-prior-next=p;p -prior=p -prior-prior; D p-prior=p -next-next;p -next=p -prior-prior; 答案: A (15) 在双向循环链表中,在 p 指针所指的结点后插入 q 所指向的新结点,其修改指针的操作是()。 A p-next=q; q-prior=p;p -next-prior=q;q -next=q; B p-next=q
17、;p -next-prior=q;q -prior=p;q -next=p -next; C q-prior=p;q -next=p -next;p-next-prior=q;p -next=q; D q-prior=p;q -next=p-next;p-next=q;p -next-prior=q; 答案: C 2算法设计 题 ( 1) 将两个递增的有序链表合并为一个递增的有序链表。要求结果链表仍使用原来两个链表的存储空间 , 不另外占用其它的存储空间。表中不允许有重复的数据。 题目分析 合并后的新表使用头指针 Lc 指向, pa 和 pb 分别是链表 La 和 Lb 的工作指针 ,初始化为
18、相应链表的第一个结点, 从第一个结点开始进行比较, 当两个链表 La 和 Lb 均为 到达表尾结点 时,依次摘取其中较小者重新链接在 Lc 表的最后。如果两个表中的元素相等,只摘取 La表中的元素,删除 Lb 表中的元素,这样确保合并后表中无重复的元素。当一个表 到达表尾结点, 为空时,将非空表的剩余元素直接链接在 Lc 表的最后。 算法描述 void MergeList(LinkList pb=Lb-next; /pa 和 pb 分别是链表 La 和 Lb 的工作指针 ,初始化为相应链表的第一个结点 Lc=pc=La; /用 La 的头结点作为 Lc 的头结点 while(pa pc=pa;
19、pa=pa-next; /取较小者 La 中的元素,将 pa 链接在 pc 的后面, pa 指针后移 else if(pa-datapb-data) pc-next=pb; pc=pb; pb=pb-next; /取较小者 Lb 中的元素,将 pb 链接在 pc 的后面, pb 指针后移 8 else /相等时取 La 中的元素,删除 Lb 中的元素 pc-next=pa;pc=pa;pa=pa-next; q=pb-next;delete pb ;pb =q; pc-next=pa?pa:pb; /插入剩余段 delete Lb; /释放 Lb 的头结点 ( 2) 将两个非递减的有序链表合并
20、为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间 , 不另外占用其它的存储空间。表中允许有重复的数据。 题目分析 合并后的新表使用头指针 Lc 指向, pa 和 pb 分别是链表 La 和 Lb 的工作指针 ,初始化为相应链表的第一个结点, 从第一个结点开始进行比较, 当两个链表 La 和 Lb 均为 到达表尾结点 时,依次摘取其中较小者重新链接在 Lc 表的表头结点之后,如果两个表中的元素相等,只摘取 La 表中的元素,保留 Lb 表中的元素。当一个表 到达表尾结点, 为空时,将非空表的剩余元素依次摘取,链接在 Lc 表的表头结点之后。 算法描述 void MergeList
21、(LinkList pb=Lb-next; /pa 和 pb 分别是链表 La 和 Lb 的工作指针 ,初始化为相应链表的第一个结点 Lc=pc=La; /用 La 的头结点作为 Lc 的头结点 Lc-next=NULL; while(pa|pb ) /只要存在一个非空表,用 q 指向待摘取的元素 if(!pa) q=pb; pb=pb-next; /La 表为空,用 q 指向 pb, pb 指针后移 else if(!pb) q=pa; pa=pa-next; /Lb 表为空,用 q 指向 pa, pa 指针后移 else if(pa-datadata) q=pa; pa=pa-next; /取较小者(包括相等) La 中的元素,用 q 指向 pa, pa 指针后移 else q=pb; pb=pb-next; /取较小者 Lb 中的元素,用 q 指向 pb, pb 指针后移 q-next = Lc-next; Lc-next = q; /将 q 指向的结点插在 Lc 表的表头结点之后 delete Lb; /释放 Lb 的头结点