1、数据结构课程例题讲解,计算机与电子工程学院 石彪,2,第一章 概述,例题1:分析以下程序段的时间复杂度。 a=0;b=1; for(i=2;i=n;i+) s=a+b; b=a; a=S; ,3,解: 因为,语句的频度是2; 语句的频度是n; 语句的频度是n-1; 语句的频度是n-1; 语句的频度是n-1; 故,该程序段的时间复杂度T(n)=2+n+3*(n-1)=4n-1=O(n)。,4,例题2:分析以下程序段的时间复杂度。 inti,j,k; For(i=0;in;i+ For(j=0;jn;j+ cij=0; for(k=0;kn;k+ cij=cij+aik+bkj; ,5,解: 语句
2、的循环控制变量i要增加到n,测试到i=n成立才会终止,故它的频度为n+1; 语句作为语句循环体内的语句应该执行n次,但语句本身要执行n+1次,故语句的频度是 n (n+1); 同理可得语句、和的频度分别是n2,n2(n+1)和n3。该程序段所有语句的频度之和为:T(n)=2n3+3n2+2n+1 其复杂度为O(n3)。,6,第二章 线性表及其顺序存储,例题1:已知一个顺序表中的元素按元素值非递减有序排列,编写一个函数删除表中多余的值相同的元素。 解:本题的算法思想是:由于顺序表中元素已按元素值非递减有序排列,值相同的元素比为相邻的元素,因此依次比较相邻两个元素,若值相等,则删除其中一个,否则继
3、续向后查找,直到最后一个元素。实现本题功能的函数如下:,7,voiddel ( seqlist*a ) int i=0, j; while ( ilength)if ( a-datai!= a-datai+1)i+;else for ( j=i; jlength; j+) a-dataj=a-dataj+1;a-length-; ,8,例题2:利用栈的基本操作,写一个返回栈中结点个数的算法int StackSize (SeqStackS),并说明S为何不用作为指针参数?,9,解: 根据题意,设一变量count来统计栈中结点的个数,从栈顶元素出发,循环执行出栈运算,直到栈空。实现本题功能的函数如
4、下: intStackSize (SeqStackS) intcount=0; while (!StackEmpty (S) conut+; Pop (s); 说明:依据题意,该算法只需统计栈中结点个数,执行完函数后不能修改实参栈的内容。所以,在该函数中,S不能用作指针参数。,10,单选题,1、下列4种基本的逻辑结构中,数据元素之间关系最弱的是( )。 A集合 B线性结构 C树状结构 D图(网)状结构,第三章 线性表及其链式存储,11,2.线性表采用链式存储结构时,内存中可用存储单元的地址( ) A.必须是连续的 B.部分地址必须是连续的C.一定是不连续的 D.连续或不连续都可以,12,3.
5、以下关于链式存储结构的叙述中,不正确的是( )。 A结点除自身信息外还包括指针域,因此存储密度小于顺序存储结构 B逻辑上相邻的结点物理不必邻接 C可以通过计算直接确定第i个结点的存储地址 D插入、删除运算操作方便,不必移动结点,13,4. 下面叙述正确的是( ) A在顺序存储的线性表中,逻辑上相继的两个数据元素在物理位置并不一定紧邻B链式存储的线性表可以随机存取C顺序存储的线性表可以随机存取D在线性表的顺序存储结构中,插入和删除元素时,移动元素的个素仅与元素的位置有关,14,5.若已知一个栈的入栈序列是1,2,3,n, 则其不可能的输出序列为为 ( )4, 3 ,2 ,1 1, 2, 3, 4
6、1, 3, 2,4 1, 4, 2,3,15,6.数组用来表示一个循环队列,为当前队列头元素的前一位置,为队尾元素的位置,假定队列中元素的个数小于,计算队列中元素的公式为 .rf; .(nfr)% n; .nrf; .(nrf)% n,16,7.用一个大小为6的数组来实现循环队列,且当前rear和front的值分别为0和3,当从队列中删除一个元素,再加入两个元素后,rear和front的值分别为 A. 1和 5 B. 2和4 C. 4和2 D. 5和1,17,8.带头结点的循环链表head为空的判定条件全( )。 Ahead;NULL BHeadnextNUL Cheadnexthead DH
7、ead!NULL,18,9、从栈顶指针为Top的链栈中删除一个结点,并将被删节点的值保存到x中,其操作步骤为( )A、x=Top-info; Top=Top-next B、Top=Top-next; x=Top-infoC、x=Top; Top=Top-next D、x=Top-info,19,例题1:下述算法的功能是什么? LinkNodeDemo(LinkListL)/L是无头结点的单链表 ListNode*P,*Q; If (L Return L: ,20,解: 该算法的功能为,将单链表L的最后一个结点移动 到原来单链表的第一个元素结点的前面,变成倒数第二个结点; 同时原来的第一个结点变
8、成了倒数第一个结点原来的第二个结点变成了新链表的第一个结点,21,例题2:有一个单链表,其结点的元素值以非递减有序排列,编写一个函数删除该单链表中多余的元素值相同的结点。解:本题采用的算法是:从头到尾扫描该单链表,并作这样的操作:若当前结点的元素值与后续结点的元素值不相等,则指针后移,否则删除该后续结点,直到扫描所有的结点。实现本题功能的函数如下:,22,node *del(head) node *head; node *q; if (head!= NULL) /*当前结点的元素值与后续结点的元素值不相等,则指针后移,否则删除该后续结点*/while(p-next!=NULL)if(p-dat
9、a!=p-next-data)p=p-next;elseq=p-next;p-next=q-next;free(q); return(head); ,23,例题3:下述算法的功能是什么? typedef int datatype; typedef struct link_nodeDatatype info;Struct link_node * next; node; 带头结点,24,void X(node * L) node * p, *q; p=L-next; q=p-next; L-next=NULL; while(p) p-next=L-next; L-next=p; p=q; q=q-
10、next; ,25,该算法的功能是将线性表带头节点的链表L(a0,a1,.an-1)就地逆置的操作,所谓“就地“指辅助空间应为O(1),26,简答题,1、在单链表、双链表和单循环链表中,若仅知道指针p指向某结点,不知道头指针,能否将结点*p从相应的链表中删去?若可以,其时间复杂度各为多少?,27,答:下面分别讨论三种链表的情况。 1. 单链表。若指针p指向某结点时,能够根据该指针找到其直接后继,能够顺后继指针链找到*p结点后的结点。但是由于不知道其头指针,所以无法访问到p指针指向的结点的直接前趋。因此无法删去该结点。,28,2. 双链表。由于这样的链表提供双向指针,根据*p结点的前趋指针和后继
11、指针可以查找到其直接前趋和直接后继,从而可以删除该结点。其时间复杂度为O(1)。,29,3. 单循环链表。根据已知结点位置,可以直接得到其后相邻的结点位置(直接后继),又因为是循环链表,所以我们可以通过查找,得到p结点的直接前趋。因此可以删去p所指结点。其时间复杂度应为O(n)。,30,1、描述以下三个概念的区别:头指针,头结点,表头结点。头指针是指向链表中第一个结点(即表头结点)的指针;在表头结点之前附设的结点称为头结点;表头结点为链表中存储线性表中第一个数据元素的结点。若链表中附设头结点,则不管线性表是否为空表,头指针均不为空,否则表示空表的链表的头指针为空。,31,第四章,例题1:设二维
12、数组A5*6的每个元素占4个字节,已知Loc(a00)=1000,A共占多少个字节?A的终端结点a45的起始地址为多少?按行和按列优先存储时,a25的起始地址分别为多少?,32,解:A共占的字节数为:5*6*4=120 a45的起始地址为:Loc(a00)+(4*6+5)*4 =1000+116=1116 按行优先存储时,a25的起始地址为:Loc(a00)+(2*6+5)*4=1000+68=1068 按列优先存储时,a25的起始地址为:Loc(a00)+(5*5+2)*4=1000+108=10108,33,例题2:一个稀疏矩阵如下图所示,给出对应的的三元组表示。,34,第五章,例题2:求
13、两个正整数m和n的最大公约数可以用如下gcd(m,n)公式表示: (1)编写一个计算gcd(m,n)的递归过程; (2)将上述过程转换成非递归过程;,35,解: 依题意,得到实现本题功能的递归函数如下: int gcd(int m,int n) int k; if(nm)return(gcd(n,m); else if(n=0)return(m); else k=m % n; return(gcd(n,k); ,36,将上述递归函数转换成非递归函数时,使用了一个栈,用于存储调用参数和函数值,由于本题很特殊,所有情况的函数值都相等,故不需要保存函数值,且当条件满足即n=0时便退出,这里采用一个两
14、维数组作为栈,其内容如下: stacktop1存储m之值 stacktop2存储n之值 由此,实现本题功能的非递归函数如下:,37,int gcd(int m,int n) int k,top=1; stacktop1=m; stacktop2=n; while(stacktop2!=0)/*循环直到n=0为止*/ /*若mn,则(n,m)入栈*/ if(stacktop1stacktop2) k=stacktop1; top+; stacktop2=stacktop-12; stacktop2=k; else/*否则,(n,m % n)入栈*/ k=stacktop1 % stacktop2
15、; top+; stacktop1=stacktop-11; stacktop2=k; return(stacktop1); ,38,第六章 树型结构,例题1:假设在树中,结点x是结点y的双亲时,用(x,y)来表示树边。已知一棵树边的集合为:(i,m),(i,n),(e,i),(b,e),(b,d),(a,b),(g,j),(g,k),(c,g),(c,f),(h,l),(c,h),(a,c) 用树形表示法画出此树,并回答下列问题:,39,(1)哪个是根结点:(2)哪些是叶结点?(3)哪个是g的双亲? (4)哪些是g的祖先?(5)哪些是g的孩子?(6)哪些是e的子孙? (7)哪些是e的兄弟?哪
16、些是f的兄弟?(8)结点b和n的层次各是多少? (9)树的深度是多少?(10)以结点c为根的子树的深度是多少? (11)树的度数是多少?,40,解:,41,(1)根结点:a(2)叶结点:m、n、d、l、h、j、k(3)g的双亲:c (4)g的祖先:a、c(5)g的孩子:j、k(6)e的子孙:i、m、n (7)e的兄弟:d(8)b的层次:2(9)树的深度:5 f的兄弟:g、hn的层次;5 (10)以结点c为根的子树的深度:3 (11)树的度数:3,42,第七章 二叉树,例题1:假设二叉树包含的结点数据为1,3,7,2,12。 (1)画出两棵高度最大的二叉树; (2)画出两棵完全二叉树,要求每个双
17、亲结点的值大于其他孩子结点的值。,43,解: (1)两棵高度最大的二叉树如图7.1和图7.2所示。,44,(2)两棵符合条件的完全二叉树,如图7.3和图7.4所示。,45,例题2: 已知一棵二叉树的前序与中序序列分别为ABDGHCEFI和GDHBAECIF,请画出此二叉树。,A,GDHB,ECIF,46,例题3:若二叉树中各结点的值均不相同,则由二叉树的前序序列和中序序列,或由其后序序列和中序序列均能惟一地确定一棵二叉树,但由前序序列和后序序列却不一定能惟一地确定一棵二叉树,47,(1)已知一棵二叉树的前序序列和中序序列分别为ABDGHCEFI和GDHBAECIF,请画出此二叉树。 (2)已知
18、一棵二叉树的中序序列和后序序列分别为BDCEAFHG和DECBHGFA,请画出此二叉树。 (3)已知两棵二叉树的前序序列和后序序列均为AB和BA,请画出这两棵不同的二叉树。,48,例4、试找出分别满足下面条件的所有二叉树: (1)前序序列和中序序列相同; (2)中序序列和后序序列相同; (3)前序序列和后序序列相同; (4)前序、中序、后序序列均相同。,49,解答: (1)空二叉树或任一结点均无左子树的非空二叉树 (2)空二叉树或任一结点均无右子树的非空二叉树 (3)空二叉树或仅有一个结点的二叉树 (4)同(3),50,例5 、给定一组数据8,2,7,5,3,12,10,以它们构造一棵哈夫曼树
19、,求出树的深度及带权路径值。 (规定左节点的权不大于右节点的权,应该如何画呢),51,树的深度为5. 带权路径长度WPL=(10+7+8)*2+5*3+(2+3)*4=85,52,7、将下列森林转化成二叉树,53,54,1、分别画出右图所示二叉树的二叉链表和顺序存储结构。,55,分别画出图4-1所示二叉树的二叉链表和顺序存储结构,0 1 2 3 4 5 6 7 8 9,10 11 12 13 14 15 16 17 18, , ,顺序表示,二叉链表表示,。,56,选择题:,1.深度为8的满二叉树有 个结点 255 127 64 632.以下说法错误的是 。 A完全二叉树上结点之间的父子关系可由
20、它们编号之间的关系来表达 B完全二叉树可以很容易用数组来存储,很容易的求出某个节点的双亲及孩子 C在二叉链表上,求根,求左、右孩子等很容易实现 D在二叉链表上,求双亲运算的时间性能很好,57,3.下列说法中正确的是 二叉树中任何一个结点的度都为2 二叉树的度都为2 一棵二叉树的度可以小于2 任何一棵二叉树中至少有一个结点的度为,58,第八章,59,例题1:给出如图8.1所示的无向图G的邻接矩阵和邻接表两种存储结构,。,图8.1一个无向图G,60,图8.2 图8.1的邻接矩阵,61,图8.2一个邻接表,62,例题2:使用普里姆算法构造出如图8.3所示的图G的一棵最小生成树。,图8.3一个无向图G
21、,63,图8.4构造最小生成树的过程,64,例题3:使用克鲁斯卡尔算法构造出如图8.5所示的图G的一棵最小生成树。,图8.5一个无向图G,65,解:使用克鲁斯卡尔算法构造棵最小生成树的过程如图8.6所示。,图8.6构造最小生成树的过程,66,例4:对如下图分别用深度优先和广度优先方法进行遍历,深度优先123645789 广度优先15237846 ,67,例5:拓扑排序的结果不是唯一的,对下图进行拓扑排序,试写出其中任意4个不同的拓扑排序列。,68,第九章,例题1:设有一组关键字19,01,23,14,55,20,84,27,68,11,10,77,采用哈希函数: H(key)= key % 1
22、3 采用开放地址法的线性探测再散列方法解决冲突,试在018的散列地址空间中对该关键字序列构造哈希表。,69,第十章,1下列关键字序列中,( D )是堆。 )16, 72, 31, 23, 94, 53 ) 94, 23, 31, 72, 16, 53 ) 16, 53, 23, 94,31, 72 ) 16, 23, 53, 31, 94, 72,70,2. 假定对元素序列(7, 3, 5, 9, 1, 12)进行堆排序,并且采用小根堆,则由初始数据构成的初始堆为( B )。A. 1, 3, 5, 7, 9, 12 B. 1, 3, 5, 9, 7, 12C. 1, 5, 3, 7, 9, 1
23、2 D. 1, 5, 3, 9, 12, 7,71,例题1:对给定关键字(28,07,39,10,65,14,61,17,50,21)选择第一个元素28进行划分,写出其快速排序第一遍的排序过程。,初始序列: 28,07,39,10,65,14,61,17,50,21 21移动: 21,07,39,10,65,14,61,17,50, 39移动:21,07,10,65,14,61,17,50,39 17移动:21,07,17,10,65,14,61,50,39 65移动:21,07,17,10,14,61,65,50,39 14移动: 21,07,17,10,14,28,61,65,50,39,
24、72,例题2:已知序列503,87,512,61,908,170,897,275,652,462,采用快速排序法对该序列作升序排序时的每一趟的结果。 (要求熟练掌握),解:依题意,采用快速排序法排序的各趟的结果如下 初始:503,87,512,61,908,170,897,275,652,462 第1趟:462,87,275,61,170 503897,908,652,512 第2趟:170,87,275,61 462,503 897,908,652,512 第3趟:61,87 170 275 462,503 897,908,652,512 第4趟:61 87 170 275 462,503 897,908,652,512 第5趟:61,87,170 275 462,503 897,908,652,512 第6趟:61,87,170,275,462,503 897,908,652,512 第7趟:61,87,170,275,462,503 512,652 897 908 第8趟:61,87,170,275,462,503,512 652 897 908 第9趟:61,87,170,275,462,503,512,652,897 908 第10趟:61,87,170,275,462,503,512,652,897,908,