数据结构课后习题答案清华大学出版社殷人昆
数据结构(C语言版清华大学出版社)-章课后部分答案
第八章选择题1. C2.A3.B4.C5.D6.B7.B8.A9.D 10.D 11.C 12.C填空题1.n、n+12. 43.8.25( 折半查找所在块 )4.左子树、右子树5.266.顺序、(n+1)/2、O(log2n)7.m-1、[m/2]-18.直接定址应用题1.进行折半查找时,判定树是唯一的,折半查找过程是走了一条从根节点到末端节点的路径,所以其最大查找长度为判定树深度[log2n]+1.其平均查找长度约为[log2n+1]-1.在二叉排序树上查找时,其最大查找长度也是与二叉树的深度相关,但是含有n个节点的二叉排序树不是唯一的,当对n个元素的有序序列构造一棵二叉排序树时,得到的二叉排序树的深度也为n,在该二叉树上查找就演变成顺序查找,此时的最大查找长度为n;在随机情况下二叉排序树的平均查找长度为1+4log2n。
因此就查找效率而言,二分查找的效率优于二叉排序树查找,但是二叉排序树便于插入和删除,在该方面性能更优。
3. 评价哈希函数优劣的因素有:能否将关键字均匀的映射到哈希表中,有无好的处理冲突的方法,哈希函数的计算是否简单等。
冲突的概念:若两个不同的关键字Ki和Kj,其对应的哈希地址Hash(Ki) =Hash(Kj),则称为地址冲突,称Ki和K,j为同义词。
(1)开放定址法(2)重哈希法(3)链接地址法4.(1)构造的二叉排序树,如图(2)中序遍历结果如下:10 12 15 20 24 28 30 35 46 50 55 68(4)平均查找长度如下:ASLsucc = (1x1+2x2+3x3+4x3+5x3)/12 = 41/128.哈希地址如下:H(35) = 35%11 = 2H(67) = 67%11 = 1H(42) = 42%11 = 9H(21) = 21%11 = 10H(29) = 29%11 = 7H(86) = 86%11 = 9H(95) = 95%11 = 7H(47) = 47%11 = 3H(50) = 50%11 = 6H(36) = 36%11 = 3H(91) = 91%11 = 3第九章选择题1. D2.C3.B4.D5.C6.B7.A8.A9.D 10.D填空题1.插入排序、交换排序、选择排序、归并排序2.移动(或者交换)3.归并排序、快速排序、堆排序4.保存当前要插入的记录,可以省去在查找插入位置时的对是否出界的判断5.O(n)、O(log2n)6.直接插入排序或者改进了的冒泡排序、快速排序7.Log2n、n8.完全二叉树、n/29.1510.{12 38 25 35 50 74 63 90}应用题11.(1)Shell排序(步长为5 3 1)每趟的排序结果初始序列为100 87 52 61 27 170 37 45 61 118 14 88 32步长为5的排序14 37 32 61 27 100 87 45 61 118 170 88 52步长为3的排序结果14 27 32 52 37 61 61 45 88 87 170 100 118步长为1的排序结果14 27 32 37 45 52 61 61 87 88 100 118最后结果14 27 32 37 45 52 61 61 87 88 100 118 170(2)快速排序每趟的排序结果如图初始序列100 87 52 61 27 170 37 45 61 118 14 88 32第一趟排序[32 87 52 61 27 88 37 45 61 14]100[118 170]第二趟排序[14 27]32[61 52 88 37 45 61 87]100 118[170]第三趟排序14[27]32[45 52 37]61[88 61 87]100 118[170]第四趟排序14[27]32[37]45[52]61[87 61]88 100 118[170]第五趟排序14[27]32[37]45[52]61[87 61]88 100 118[170]最后结果14[27]32[37]45[52]61[61]87 88 100 118[170](3)二路归并排序每趟的排序结果初始序列[100][87][52][61][27][170][37][45][61][118][14][88][32]第一趟归并[87 100][52 61][27 170][37 45][61 118][14 88][32]第二趟归并[52 61 87 100][27 37 45 170][14 61 88 118][32]第三趟归并排序[27 37 45 52 61 87 100 170][14 32 61 88 118]第四趟归并排序[14 27 32 37 45 52 61 61 87 88 100 118 170]最后结果14 27 32 37 45 52 61 61 87 88 100 118 17012.采用快速排序时,第一趟排序过程中的数据移动如图:算法设计题1.分析:为讨论方便,待排序记录的定义为(后面各算法都采用此定义):#define MAXSIZE 100 /* 顺序表的最大长度,假定顺序表的长度为100 */ typedef int KeyType; /* 假定关键字类型为整数类型 */typedef struct {KeyType key; /* 关键字项 */OtherType other; /* 其他项 */}DataType; /* 数据元素类型 */typedef struct {DataType R[MAXSIZE+1]; /* R[0]闲置或者充当哨站 */int length; /* 顺序表长度 */}sqList; /* 顺序表类型 */设n个整数存储在R[1..n]中,因为前n-2个元素有序,若采用直接插入算法,共要比较和移动n-2次,如果最后两个元素做一个批处理,那么比较次数和移动次数将大大减小。
清华大学出版社数据结构(C++版)(第2版)课后习题答案最全整理
清华大学出版社数据结构(C++版)(第2版)课后习题答案最全整理第1 章绪论课后习题讲解1. 填空⑴()是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。
【解答】数据元素⑵()是数据的最小单位,()是讨论数据结构时涉及的最小数据单位。
【解答】数据项,数据元素【分析】数据结构指的是数据元素以及数据元素之间的关系。
⑶从逻辑关系上讲,数据结构主要分为()、()、()和()。
【解答】集合,线性结构,树结构,图结构⑷数据的存储结构主要有()和()两种基本方法,不论哪种存储结构,都要存储两方面的内容:()和()。
【解答】顺序存储结构,链接存储结构,数据元素,数据元素之间的关系⑸算法具有五个特性,分别是()、()、()、()、()。
【解答】有零个或多个输入,有一个或多个输出,有穷性,确定性,可行性⑹算法的描述方法通常有()、()、()和()四种,其中,()被称为算法语言。
【解答】自然语言,程序设计语言,流程图,伪代码,伪代码⑺在一般情况下,一个算法的时间复杂度是()的函数。
【解答】问题规模⑻设待处理问题的规模为n,若一个算法的时间复杂度为一个常数,则表示成数量级的形式为(),若为n*log25n,则表示成数量级的形式为()。
【解答】Ο(1),Ο(nlog2n)【分析】用大O记号表示算法的时间复杂度,需要将低次幂去掉,将最高次幂的系数去掉。
2. 选择题⑴顺序存储结构中数据元素之间的逻辑关系是由()表示的,链接存储结构中的数据元素之间的逻辑关系是由()表示的。
A 线性结构B 非线性结构C 存储位置D 指针【解答】C,D【分析】顺序存储结构就是用一维数组存储数据结构中的数据元素,其逻辑关系由存储位置(即元素在数组中的下标)表示;链接存储结构中一个数据元素对应链表中的一个结点,元素之间的逻辑关系由结点中的指针表示。
⑵假设有如下遗产继承规则:丈夫和妻子可以相互继承遗产;子女可以继承父亲或母亲的遗产;子女间不能相互继承。
数据结构(C 语言 清华出版社)习题答案
习题1参考答案一、单项选择题1. A2. C3. D4. B5. C、A6. C、B7. B8. D9. B 10. B二、填空题1.线性结构,非线性结构2.集合,线性,树,图3.一对一,一对多或多对多4. 时间,空间5. 前趋,一,后继,多6. 有多个7. 一对一,一对多,多对多8. O(2n)9. O(n)10. O(2n)11. O(log3n)12. 程序对于精心设计的典型合法数据输入能得出符合要求的结果。
13. 事后统计,事前估计三、算法设计题1. O(2n)2. O(2n)3. O(n3)4. O(n)5. O(n)习题2参考答案一、单项选择题1.A 2.A 3.D 4.C 5.D 6.A 7.B 8.B 9.C 10.A 11.D 12.B 13.C 14.B 15.C 16.C 17.B 18.D 19.C 20.A二、填空题1.线性2.n-i+1 3.相邻4.前移,前,后5.物理存储位置,链域的指针值6.前趋,后继7.顺序,链接8.一定,不一定9.线性,任何,栈顶,队尾,队头10.单链表,双链表,非循环链表,循环链表11.使空表和非空表统一;算法处理一致12.O(1),O(n)13.栈满,栈空,m,栈底,两个栈的栈顶在栈空间的某一位置相遇14.2、3;15.O(1)三、简答题1.头指针是指向链表中第一个结点(即表头结点)的指针;在表头结点之前附设的结点称为头结点;表头结点为链表中存储线性表中第一个数据元素的结点。
若链表中附设头结点,则不管线性表是否为空表,头指针均不为空,否则表示空表的链表的头指针为空。
2.线性表具有两种存储结构即顺序存储结构和链接存储结构。
线性表的顺序存储结构可以直接存取数据元素,方便灵活、效率高,但插入、删除操作时将会引起元素的大量移动,因而降低效率:而在链接存储结构中内存采用动态分配,利用率高,但需增设指示结点之间关系的指针域,存取数据元素不如顺序存储方便,但结点的插入、删除操作较简单。
数据结构(C语言版)清华大学出版社课后题1-5章答案
数据结构(C语言版)清华大学出版社课后题1-5章答案第一章选择题1.A2.B3.C4.D5.B6.C第二章选择题1.A2.D3.D4.C5.A6.C7.B8.B9.D 10.D应用题1.应该选用链接存储表示。
如果才用顺序表示法,必须在一个连续的可用空间中为这N 个表分配空间。
初始时候因为不知道哪个表增长得快,必须平均分配空间。
在程序运行过程中,有的表占用的空间增长得快,有的表占用空间增长得慢,有的表很快就使用完了分配给它的空间,有的表才占用了少许空间,在进行元素的插入时候就必须成片的移动其他表的空间,以空出位置进行插入;在元素删除时为填补空白,也可能移动许多元素。
这个处理过程及其繁琐和低效。
如果采用链接存储,一个表的空间可以连续也可以不连续。
表的增长通过动态分配内存得以解决,只要存储器未满,就不会发生表溢出;表的收缩可以通过动态存储释放实现,释放的空间还可以在以后动态分配给其他的存储需求,非常灵活方便。
对于N个表(包括表的总数可能变化)共存的情形,处理十分简单快捷,插入、删除时间复杂度为O(1)。
所以才用链接存储表示较好。
2.一般来说,链式存储结构克服了顺序存储结构的三个缺点。
首先,插入、删除操作不需要移动元素,只修改指针;其次,不需要预先分配空间,可根据需要动态申请空间;其三,表容量只受到内存空间的限制。
其缺点是因为指针增加了空间开销,当空间不允许时,就不能克服顺序存储的缺点。
3.顺序结构时ai与ai+1的物理位置相邻,链表结构时两者的位置不要求一定相邻。
7.在顺序表中插入和删除一个节点需平均移动全表一半的节点。
具体的移动次数取决于所插入和删除的节点的位置i和全表的长度n这两个因素。
算法设计题1.分析:遍历整个顺序表,用k记录在x~y之间元素的个数,k的初始值为0。
对于当前遍历到的元素,若其值在x~y之间,则前移k个位置;否则执行++k。
这样每个不在x~y之间的元素仅仅移动一次,所以效率较高。
数据结构(c语言版)第三版清华大学出版社习题参考答案
不管怎样,生活还是要继续向前走去。
有的时候伤害和失败不见得是一件坏事,它会让你变得更好,孤单和失落亦是如此。
每件事到最后一定会变成一件好事,只要你能够走到最后。
附录习题参考答案习题1参考答案1.1.选择题(1). A. (2). A. (3). A. (4). B.C. (5). A. (6). A. (7). C. (8). A. (9). B. (10.) A.1.2.填空题(1). 数据关系(2). 逻辑结构物理结构(3). 线性数据结构树型结构图结构(4). 顺序存储链式存储索引存储散列表(Hash)存储(5). 变量的取值范围操作的类别(6). 数据元素间的逻辑关系数据元素存储方式或者数据元素的物理关系(7). 关系网状结构树结构(8). 空间复杂度和时间复杂度(9). 空间时间(10). Ο(n)1.3 名词解释如下:数据:数据是信息的载体是计算机程序加工和处理的对象包括数值数据和非数值数据数据项:数据项指不可分割的、具有独立意义的最小数据单位数据项有时也称为字段或域数据元素:数据元素是数据的基本单位在计算机程序中通常作为一个整体进行考虑和处理一个数据元素可由若干个数据项组成数据逻辑结构:数据的逻辑结构就是指数据元素间的关系数据存储结构:数据的物理结构表示数据元素的存储方式或者数据元素的物理关系数据类型:是指变量的取值范围和所能够进行的操作的总和算法:是对特定问题求解步骤的一种描述是指令的有限序列1.4 语句的时间复杂度为:(1) Ο(n2)(2) Ο(n2)(3) Ο(n2)(4) Ο(n-1)(5) Ο(n3) 1.5 参考程序:main(){int XYZ;scanf("%d %d%d"&X&YZ);if (X>=Y)if(X>=Z)if (Y>=Z) { printf("%d %d%d"XYZ);}else{ printf("%d %d%d"XZY);}else{ printf("%d %d%d"ZXY);}else if(Z>=X)if (Y>=Z) { printf("%d %d%d"YZX);}else{ printf("%d%d%d"ZYX);}else{ printf("%d%d%d"YXZ);}}1.6 参考程序:main(){int in;float xa[]p;printf("\nn=");scanf("%f"&n);printf("\nx=");scanf("%f"&x);for(i=0;i<=n;i++)scanf("%f "&a[i]);p=a[0];for(i=1;i<=n;i++){ p=p+a[i]*x;x=x*x;}printf("%f"p)'}习题2参考答案2.1选择题(1). C. (2). B. (3). B. (4). B. 5. D. 6. B. 7. B. 8. A. 9. A. 10. D.2.2.填空题(1). 有限序列(2). 顺序存储和链式存储(3). O(n) O(n)(4). n-i+1 n-i(5). 链式(6). 数据指针(7). 前驱后继(8). Ο(1) Ο(n)(9). s->next=p->next; p->next=s ;(10). s->next2.3. 解题思路:将顺序表A中的元素输入数组a若数组a中元素个数为n将下标为012...(n-1)/2的元素依次与下标为nn-1...(n-1)/2的元素交换输出数组a的元素参考程序如下:main(){int in;float ta[];printf("\nn=");scanf("%f"&n);for(i=0;i<=n-1;i++)scanf("%f "&a[i]);for(i=0;i<=(n-1)/2;i++){ t=a[i]; a[i] =a[n-1-i]; a[n-1-i]=t;} for(i=0;i<=n-1;i++)printf("%f"a[i]);}2.4 算法与程序:main(){int in;float ta[];printf("\nn=");scanf("%f"&n);for(i=0;i<n;i++)scanf("%f "&a[i]);for(i=1;i<n;i++)if(a[i]>a[0]{ t=a[i]; a[i] =a[0]; a[0]=t;} printf("%f"a[0]);for(i=2;i<n;i++)if(a[i]>a[1]{ t=a[i]; a[i] =a[1]; a[1]=t;} printf("%f"a[0]);}2.5 算法与程序:main(){int ijkn;float xta[];printf("\nx=");scanf("%f"&x);printf("\nn=");scanf("%f"&n);for(i=0;i<n;i++)scanf("%f "&a[i]); // 输入线性表中的元素for (i=0; i<n; i++) { // 对线性表中的元素递增排序 k=i;for (j=i+1; j<n; j++) if (a[j]<a[k]) k=j;if (k<>j) {t=a[i];a[i]=a[k];a[k]=t;}}for(i=0;i<n;i++) // 在线性表中找到合适的位置if(a[i]>x) break;for(k=n-1;k>=i;i--) // 移动线性表中元素然后插入元素xa[k+1]=a[k];a[i]=x;for(i=0;i<=n;i++) // 依次输出线性表中的元素printf("%f"a[i]);}2.6 算法思路:依次扫描A和B的元素比较A、B当前的元素的值将较小值的元素赋给C如此直到一个线性表扫描完毕最后将未扫描完顺序表中的余下部分赋给C即可C的容量要能够容纳A、B两个线性表相加的长度有序表的合并算法:void merge (SeqList ASeqList BSeqList *C){ int ijk;i=0;j=0;k=0;while ( i<=st && j<=st )if (A.data[i]<=B.data[j])C->data[k++]=A.data[i++];elseC->data[k++]=B.data[j++];while (i<=st )C->data[k++]= A.data[i++];while (j<=st )C->data[k++]=B.data[j++];C->last=k-1;}2.7 算法思路:依次将A中的元素和B的元素比较将值相等的元素赋给C如此直到线性表扫描完毕线性表C就是所求递增有序线性表算法:void merge (SeqList ASeqList BSeqList *C){ int ijk;i=0;j=0;k=0;while ( i<=st)while(j<=st )if (A.data[i]=B.data[j])C->data[k++]=A.data[i++];C->last=k-1;}习题3参考答案3.1.选择题(1). D (2). C (3). D (4). C (5). B (6). C (7). C (8). C (9). B (10).AB (11). D (12). B (13). D (14). C (15). C (16). D(17). D (18). C (19). C (20). C 3.2.填空题(1) FILOFIFO(2) -13 4 X * + 2 Y * 3 / -(3) stack.topstack.s[stack.top]=x(4) p>llink->rlink=p->rlinkp->rlink->llink=p->rlink(5) (R-F+M)%M(6) top1+1=top2(7) F==R(8) front==rear(9) front==(rear+1)%n(10) N-13.3 答:一般线性表使用数组来表示的线性表一般有插入、删除、读取等对于任意元素的操作而栈只是一种特殊的线性表栈只能在线性表的一端插入(称为入栈push)或者读取栈顶元素或者称为"弹出、出栈"(pop)3.4 答:相同点:栈和队列都是特殊的线性表只在端点处进行插入删除操作不同点:栈只在一端(栈顶)进行插入删除操作;队列在一端(top)删除一端(rear)插入3.5 答:可能序列有14种:ABCD; ACBD; ACDB; ABDC; ADCB; BACD; BADC; BCAD; BCDA; BDCA; CBAD; CBDA; CDBA; DCBA3.6 答:不能得到435612最先出栈的是4则按321的方式出不可能得到1在2前的序列可以得到135426按如下方式进行push(1)pop()push(2)push(3)pop()push(4)push(5)pop()pop()pop()push(6)pop()3.7 答:stack3.8 非递归:int vonvert (int noint a[]) //将十进制数转换为2进制存放在a[] 并返回位数{int r;SeStack s*p;P=&s;Init_stack(p);while(no){push(pno%2);no/=10;}r=0;while(!empty_stack(p)){pop(pa+r);r++;}return r;}递归算法:void convert(int no){if(no/2>0){Convert(no/2);Printf("%d"no%2);}elseprintf("%d"no);}3.9 参考程序:void view(SeStack s){SeStack *p; //假设栈元素为字符型char c;p=&s;while(!empty_stack(p)){c=pop(p);printf("%c"c);}printf("\n");}3.10 答:char3.11 参考程序:void out(linkqueue q){int e;while(q.rear !=q.front ){dequeue(qe);print(e); //打印}}习题4参考答案4.1 选择题:(1). A (2). D (3). C (4). C (5). B (6). B (7). D (8). A (9). B (10). D 4.2 填空题:(1)串长相等且对应位置字符相等(2)不含任何元素的串(3)所含字符均是空格所含空格数(4) 10(5) "hello boy"(6) 13(7) 1066(8)模式匹配(9)串中所含不同字符的个数(10) 364.3 StrLength (s)=14StrLength (t)=4SubStr( s87)=" STUDENT"SubStr(t21)="O"StrIndex(s"A")=3StrIndex (st)=0StrRep(s"STUDENT"q)=" I AM A WORKER"4.4 StrRep(s"Y""+");StrRep(s"+*""*Y");4.5 空串:不含任何字符;空格串:所含字符都是空格串变量和串常量:串常量在程序的执行过程中只能引用不能改变;串变量的值在程序执行过程中是可以改变和重新赋值的主串与子串:子串是主串的一个子集串变量的名字与串变量的值:串变量的名字表示串值的标识符4.6int EQUAl(ST){char *p*q;p=&S;q=&T;while(*p&&*q){if(*p!=*q)return *p-*q;p++;q++;}return *p-*q;}4.7(1)6*8*6=288(2)1000+47*6=1282(3)1000+(8+4)*8=1096(4)1000+(6*7+4)*8=13684.8习题5参考答案5.1 选择(1)C(2)B(3)C(4)B(5)C(6)D(7)C(8)C(9)B(10)C (11)B(12)C(13)C(14)C(15)C(16)B5.2 填空(1)1(2)1036;1040(3)2i(4) 1 ; n ; n-1 ; 2(5)2k-1;2k-1(6)ACDBGJKIHFE(7)p!=NULL(8)Huffman树(9)其第一个孩子; 下一个兄弟(10)先序遍历;中序遍历5.3叶子结点:C、F、G、L、I、M、K;非终端结点:A、B、D、E、J;各结点的度:结点: A B C D E F G L I J K M度: 4 3 0 1 2 0 0 0 0 1 0 0树深:45.4无序树形态如下:二叉树形态如下:5.5二叉链表如下:三叉链表如下:5.6先序遍历序列:ABDEHICFJG中序遍历序列:DBHEIAFJCG后序遍历序列:DHIEBJFGCA5.7(1) 先序序列和中序序列相同:空树或缺左子树的单支树;(2) 后序序列和中序序列相同:空树或缺右子树的单支树;(3) 先序序列和后序序列相同:空树或只有根结点的二叉树5.8这棵二叉树为:5.9先根遍历序列:ABFGLCDIEJMK后根遍历序列:FGLBCIDMJKEA层次遍历序列:ABCDEFGLIJKM5.10证明:设树中结点总数为n叶子结点数为n0则n=n0 + n1 + ...... + nm (1)再设树中分支数目为B则B=n1 + 2n2 + 3n3 + ...... + m nm (2)因为除根结点外每个结点均对应一个进入它的分支所以有n= B + 1 (3)将(1)和(2)代入(3)得n0 + n1 + ...... + nm = n1 + 2n2 + 3n3 + ...... + m nm + 1 从而可得叶子结点数为:n0 = n2 + 2n3 + ...... + (m-1)nm + 15.11由5.10结论得n0 = (k-1)nk + 1又由 n=n0 + nk得nk= n-n0代入上式得n0 = (k-1)(n-n0)+ 1叶子结点数为:n0 = n (k-1) / k5.12int NodeCount(BiTree T){ //计算结点总数if(T)if (T-> lchild==NULL )&&( T --> rchild==NULL )return 1;elsereturn NodeCount(T-> lchild ) +Node ( T --> rchild )+1; elsereturn 0;5.13void ExchangeLR(Bitree bt){/* 将bt所指二叉树中所有结点的左、右子树相互交换 */ if (bt && (bt->lchild || bt->rchild)) {bt->lchild<->bt->rchild;Exchange-lr(bt->lchild);Exchange-lr(bt->rchild);}}/* ExchangeLR */5.14int IsFullBitree(Bitree T){/* 是则返回1否则返回0*/Init_Queue(Q); /* 初始化队列*/flag=0;In_Queue(QT); /* 根指针入队列按层次遍历*/while(!Empty_Queue (Q)){Out_Queue(Qp);if(!p) flag=1; /* 若本次出队列的是空指针时则修改flag值为1若以后出队列的指针存在非空则可断定不是完全二叉树 */else if (flag) return 0; /*断定不是完全二叉树 */ else{In_Queue(Qp->lchild);In_Queue(Qp->rchild); /* 不管孩子是否为空都入队列*/}}/* while */return 1; /* 只有从某个孩子指针开始之后所有孩子指针都为空才可断定为完全二叉树*/}/* IsFullBitree */5.15转换的二叉树为:5.16对应的森林分别为:5.17typedef char elemtype;typedef struct{ elemtype data;int parent;} NodeType;(1) 求树中结点双亲的算法:int Parent(NodeType t[ ]elemtype x){/* x不存在时返回-2否则返回x双亲的下标(根的双亲为-1 */for(i=0;i<MAXNODE;i++)if(x==t[i].data) return t[i].parent; return -2;}/*Parent*/(2) 求树中结点孩子的算法:void Children(NodeType t[ ]elemtype x){for(i=0;i<MAXNODE;i++){if(x==t[i].data)break;/*找到x退出循环*/}/*for*/if(i>=MAXNODE) printf("x不存在\n"); else {flag=0;for(j=0;j<MAXNODE;j++)if(i==t[j].parent){ printf("x的孩子:%c\n"t[j].data);flag=1;}if(flag==0) printf("x无孩子\n");}}/*Children*/5.18typedef char elemtype;typedef struct ChildNode{ int childcode;struct ChildNode *nextchild;}typedef struct{ elemtype data;struct ChildNode *firstchild;} NodeType;(1) 求树中结点双亲的算法:int ParentCL(NodeType t[ ]elemtype x){/* x不存在时返回-2否则返回x双亲的下标 */for(i=0;i<MAXNODE;i++)if(x==t[i].data) {loc=i;/*记下x的下标*/break;}if(i>=MAXNODE) return -2; /* x不存在 *//*搜索x的双亲*/for(i=0;i<MAXNODE;i++)for(p=t[i].firstchild;p!=NULL;p=p->nextchild) if(loc==p->childcode)return i; /*返回x结点的双亲下标*/}/* ParentL */(2) 求树中结点孩子的算法:void ChildrenCL(NodeType t[ ]elemtype x){for(i=0;i<MAXNODE;i++)if(x==t[i].data) /*依次打印x的孩子*/{flag=0; /* x存在 */for(p=t[i].firstchild;p;p=p->nextchild){ printf("x的孩子:%c\n"t[p-> childcode].data);flag=1;}if(flag==0) printf("x无孩子\n");return;}/*if*/printf("x不存在\n");return;}/* ChildrenL */5.19typedef char elemtype;typedef struct TreeNode{ elemtype data;struct TreeNode *firstchild; struct TreeNode *nextsibling; } NodeType;void ChildrenCSL(NodeType *telemtype x){ /* 层次遍历方法 */Init_Queue(Q); /* 初始化队列 */In_Queue(Qt);count=0;while(!Empty_Queue (Q)){Out_Queue(Qp);if(p->data==x){ /*输出x的孩子*/p=p->firstchild;if(!p) printf("无孩子\n");else{ printf("x的第%i个孩子:%c\n"++countp->data);/*输出第一个孩子*/p=p->nextsibling; /*沿右分支*/while(p){printf("x的第%i个孩子:%c\n"++countp->data);p=p-> nextsibling;}}return;}if(p-> firstchild) In_Queue(Qp-> firstchild);if(p-> nextsibling) In_Queue(Qp-> nextsibling);}}/* ChildrenCSL */5.20(1) 哈夫曼树为:(2) 在上述哈夫曼树的每个左分支上标以1右分支上标以0并设这7个字母分别为A、B、C、D、E、F和H如下图所示:则它们的哈夫曼树为分别为:A:1100B:1101C:10D:011E:00F:010H:111习题6参考答案6.1 选择题(1)C (2)A (3)B(4)C(5)B______条边(6)B(7)A(8)A(9)B(10)A(11)A(12)A(13)B(14)A(15)B(16)A(17)C 6.2 填空(1) 4(2) 1对多 ; 多对多(3) n-1 ; n(4) 0_(5)有向图(6) 1(7)一半(8)一半(9)___第i个链表中边表结点数___(10)___第i个链表中边表结点数___(11)深度优先遍历;广度优先遍历(12)O(n2)(13)___无回路6.3(1)邻接矩阵:(2)邻接链表:(3)每个顶点的度:顶点度V1 3V2 3V3 2V4 3V5 36.4(1)邻接链表:(2)逆邻接链表:(3)顶点入度出度V1 3 0V2 2 2V3 1 2V4 1 3V5 2 1V6 2 36.5(1)深度优先查找遍历序列:V1 V2 V3 V4 V5; V1 V3 V5 V4 V2; V1 V4 V3 V5 V2 (1)广度优先查找遍历序列:V1 V2 V3 V4 V5; V1 V3 V2 V4 V5; V1 V4 V3 V2 V56.6有两个连通分量:6.7顶点(1)(2)(3)(4)(5)Low Close Cost VexLow CloseCost VexLow CloseCost VexLow CloseCost VexLow CloseCost VexV10 00 00 00 00 0V21 00 00 00 00 0V31 01 00 00 00 0V43 02 12 10 10 1V5∞ 05 13 22 30 3U{v1} {v1v2} {v1v2v3} {v1 v2 v3 v4} {v1 v2 v3 v4 v5} T {} { (v1 v2) } {(v1 v2) (v1 v3) } {(v1 v2) (v1 v3) (v2 v4) } {(v1 v2)(v1v3)(v2v4)(v4v5) }最小生成树的示意图如下:6.8拓扑排序结果: V3--> V1 --> V4 --> V5 --> V2 --> V66.9(1)建立无向图邻接矩阵算法:提示:参见算法6.1因为无向图的邻接矩阵是对称的所以有for (k=0; k<G ->e; k++) /*输入e条边建立无向图邻接矩阵*/{ scanf("\n%d%d"&i&j);G ->edges[i][j]= G ->edges[j][i]=1;}(2)建立无向网邻接矩阵算法:提示:参见算法6.1初始化邻接矩阵:#define INFINITY 32768 /* 表示极大值*/for(i=0;i<G->n;i++)for(j=0;j<G->n;j++) G->edges[i][j]= INFINITY;输入边的信息:不仅要输入边邻接的两个顶点序号还要输入边上的权值for (k=0; k<G ->e; k++) /*输入e条边建立无向网邻接矩阵*/{ scanf("\n%d%d%d"&i&j&cost); /*设权值为int型*/G ->edges[i][j]= G ->edges[j][i]=cost;/*对称矩阵*/}(3)建立有向图邻接矩阵算法:提示:参见算法6.16.10(1)建立无向图邻接链表算法:typedef VertexType char;int Create_NgAdjList(ALGraph *G){ /* 输入无向图的顶点数、边数、顶点信息和边的信息建立邻接表 */scanf("%d"&n); if(n<0) return -1; /* 顶点数不能为负 */G->n=n;scanf("%d"&e); if(e<0) return =1; /*边数不能为负 */G->e=e;for(m=0;m< G->n ;m++)G-> adjlist [m].firstedge=NULL; /*置每个单链表为空表*/for(m=0;m< G->n;m++)G->adjlist[m].vertex=getchar(); /*输入各顶点的符号*/for(m=1;m<= G->e; m++){scanf("\n%d%d"&i&j); /* 输入一对邻接顶点序号*/if((i<0 || j<0) return -1;p=(EdgeNode*)malloc(sizeof(EdgeNode));/*在第i+1个链表中插入一个边表结点*/ p->adjvex=j;p->next= G-> adjlist [i].firstedge;G-> adjlist [i].firstedge=p;p=(EdgeNode*)malloc(sizeof(EdgeNode));/*在第j+1个链表中插入一个边表结点*/ p->adjvex=i;p->next= G-> adjlist [j].firstedge;G-> adjlist [j].firstedge=p;} /* for*/return 0; /*成功*/}//Create_NgAdjList(2)建立有向图逆邻接链表算法:typedef VertexType char;int Create_AdjList(ALGraph *G){ /* 输入有向图的顶点数、边数、顶点信息和边的信息建立逆邻接链表 */scanf("%d"&n); if(n<0) return -1; /* 顶点数不能为负 */G->n=n;scanf("%d"&e); if(e<0) return =1; /*弧数不能为负 */G->e=e;for(m=0;m< G->n; m++)G-> adjlist [m].firstedge=NULL; /*置每个单链表为空表*/for(m=0;m< G->n;m++)G->adjlist[m].vertex=getchar(); /*输入各顶点的符号*/for(m=1;m<= G->e ; m++){scanf("\n%d%d"&t&h); /* 输入弧尾和弧头序号*/if((t<0 || h<0) return -1;p=(EdgeNode*)malloc(sizeof(EdgeNode));/*在第h+1个链表中插入一个边表结点*/ p->adjvex=t;p->next= G-> adjlist [h].firstedge;G-> adjlist [h].firstedge=p;} /* for*/return 0; /*成功*/}//Create_AdjList6.11void Create_AdjM(ALGraph *G1MGraph *G2){ /*通过无向图的邻接链表G1生成无向图的邻接矩阵G2*/G2->n=G1->n; G2->e=G1->e;for(i=0;i<G2->n;i++) /* 置G2每个元素为0 */for(j=0;j<G2->n;j++) G2->edges[i][j]= 0;for(m=0;m< G1->n;m++)G2->vexs[m]=G1->adjlist[m].vertex; /*复制顶点信息*/num=(G1->n/2==0?G1->n/2:G1->n/2+1); /*只要搜索前n/2个单链表即可*/for(m=0;m< num;m++){ p=G1->adjlist[m].firstedge;while(p){ /* 无向图的存储具有对称性*/G2->edges[m][ p->adjvex ]= G2->edges[p->adjvex ] [m] =1;p==p->next;}}/* for */}/*Create_AdjM */6.12void Create_AdjL(ALGraph *G1MGraph *G2){ /*通过无向图的邻接矩阵G1生成无向图的邻接链表G2*/G2->n=G1->n; G2->e=G1->e;for(i=0;i<G1->n;i++) /* 建立每个单链表 */{ G2->vexs[i]=G1->adjlist[i].vertex;G2->adjlist[i].firstedge=NULL;for(j=i; j<G1->n; j++) /*对称矩阵只要搜索主对角以上的元素即可*/{ if(G1->edges[i][j]== 1){ p=(EdgeNode*)malloc(sizeof(EdgeNode));/*在第i+1个链表中插入一个边表结点*/p->adjvex=j;p->next= G-> adjlist [i].firstedge;G-> adjlist [i].firstedge=p;p=(EdgeNode*)malloc(sizeof(EdgeNode));/*在第j+1个链表中插入一个边表结点*/p->adjvex=i;p->next= G-> adjlist [j].firstedge;G-> adjlist [j].firstedge=p;}/*if*/}/* for*/}/* for*/}/* Create_AdjL */6.13(1) 邻接矩阵中1的个数的一半;(2) 若位于[i-1j-1]或[j-1i-1]位置的元素值等于1则有边相连否则没有(3) 顶点i的度等于第i-1行中或第i-1列中1的个数6.14(1) 邻接链表中边表结点的个数的一半;(2) 若第i-1(或j-1)个单链表中存在adjvex域值等于j-1(或i-1)的边表结点则有边相连否则没有(3) 顶点i的度等于第i-1个单链表中边表结点的个数6.15提示:参见算法6.2 和6.3习题 7参考答案7.1 选择题(1)C (2)C (3) C (4)B (5) A (6)A (7) D (8)B (9)D (10) B(11)B (12)A (13)C (14)C (15)A (16)D (17)C (18)BC (19)B (20)A7.2 填空题(1) O(n)O(log2n)(2) 12485log2(n+1)-1(3)小于大于(4)增序序列(5)m-1(6) 70; 342055(7) n/m(8)开放地址法链地址法(9)产生冲突的可能性就越大产生冲突的可能性就越小(10)关键码直接(11)②①⑦(12) 1616821(13)直接定址法数字分析法平方取中法折叠法除留余数法随机数法(14)开放地址法再哈希法链地址法建立一个公共溢出区(15)装满程度(16)索引快(17)哈希函数装填因子(18)一个结点(19)中序(20)等于7.3 一棵二叉排序树(又称二叉查找树)或者是一棵空树或者是一棵同时满足下列条件的二叉树:(1)若它的左子树不空则左子树上所有结点的键值均小于它根结点键值(2)若它的右子树不空则右子树上所有结点的键值均大于它根结点键值(3)它的左、右子树也分别为二叉排序树7.4 对地址单元d=H(K)如发生冲突以d为中心在左右两边交替进行探测按照二次探测法键值K的散列地址序列为:do=H(K)d1=(d0+12)mod md2=(d0-12)mod md3=(d0+22)mod md4=(d0-12)mod m......7.5 衡量算法的标准有很多时间复杂度只是其中之一尽管有些算法时间性能很好但是其他方面可能就存在着不足比如散列查找的时间性能很优越但是需要关注如何合理地构造散列函数问题而且总存在着冲突等现象为了解决冲突还得采用其他方法二分查找也是有代价的因为事先必须对整个查找区间进行排序而排序也是费时的所以常应用于频繁查找的场合对于顺序查找尽管效率不高但却比较简单常用于查找范围较小或偶而进行查找的情况7.6此法要求设立多个散列函数Hii=1...k当给定值K与闭散列表中的某个键值是相对于某个散列函数Hi的同义词因而发生冲突时继续计算该给定值K在下一个散列函数Hi+1下的散列地址直到不再产生冲突为止7.7散列表由两个一维数组组成一个称为基本表另一个称为溢出表插入首先在基本表上进行;假如发生冲突则将同义词存人溢出表7.8 结点个数为n时高度最小的树的高度为1有两层它有n-1个叶结点1个分支结点;高度最大的树的高度为n-l有n层它有1个叶结点n-1个分支结点7.9 设顺序查找以h为表头指针的有序链表若查找成功则返回结点指针p查找失败则返回null值pointer sqesrearch(pointer hint xpointerp){p=null;while(h)if(x>h->key)h=h->link;else{if(x==h->key)p=h;return(p);}}虽然链表中的结点是按从小到大的顺序排列的但是其存储结构为单链表查找结点时只能从头指针开始逐步进行搜索故不能用折半(二分)查找7.10 分析:对二叉排序树来讲其中根遍历序列为一个递增有序序列因此对给定的二叉树进行中根遍历如果始终能保证前一个值比后一个值小则说明该二叉树是二叉排序树int bsbtr (bitreptr T) /*predt记录当前结点前趋值初值为-∞*/{ if (T==NULL) return(1);else{b1=bsbtr(T->lchild);/*判断左子树*/if (!b1|| (predt>=T->data)) return(0);*当前结点和前趋比较*/ predt=T->data;/*修改当前结点的前趋值*/return(bsbtr(T->rchild));/*判断右子树并返回最终结果*/}}7.11 (1)使用线性探查再散列法来构造散列表如表下所示散列表───────────────────────────────地址 0 1 2 3 4 5 6 7 8 9 10───────────────────────────────数据 33 1 13 12 34 38 27 22───────────────────────────────(2)使用链地址法来构造散列表如下图(3)装填因子a=8/11使用线性探查再散列法查找成功所需的平均查找次数为Snl=0.5(1+1/(1-a))=0.5*(1+1/(1-8/11))=7/3使用线性探查再散列法查找不成功所需的平均查找次数为:Unl=0.5(1+1/(1-a)2)=0.5*(1+1/(1-8/11)2)=65/9 使用链地址法查找成功所需的平均查找次数为:Snc=l+a/2=1+8/22=15/11使用链地址法查找不成功所需的平均查找次数为: 'Unl=a+e-a=8/1l+e-8/117.12 分析:在等查区间的上、下界处设两个指针由此计算出中间元素的序号当中间元素大于给定值X时接下来到其低端区间去查找;当中间元素小于给定值X时接下来到其高端区间去查找;当中间元素等于给定值X时表示查找成功输出其序号Int binlist(sqtable Aint stkeytype X) /*t、s分别为查找区间的上、下界*/{ if(s<t) return(0);/*查找失败*/else{ mid=(S+t)/2;switCh(mid){case x<A.item[midJ.key: return(binlist(Asmid-lX));/*在低端区间上递归*/case x==A.item[mid].key: return(mid);/+查找成功*/ case x>A.item[mid].key: return(amid+ltX));/*在高端区间上递归*/}}}7.13int sqsearch0 (sqtable Akeytype X) /*数组有元素n个*/{ i=l;A.item[n+1].key=X;/t设置哨兵*/while (A.item[n+1].key!=X) i++;return (i% (n/1));/*找不到返回0找到返回其下标*/}查找成功平均查找长度为:(1+2+3+...+n)/n:(1+n)/2查找不成功平均查找长度为:n+17.14散列函数:H(key)=100+(key个位数+key十位数) mod l0;形成的散列表:100 101 102 103 104 105 106 107 108 10998 75 63 46 49 79 61 53 17查找成功时的平均长度为:(1+2+1+1+5+1+1+5+5+3)/10=2.5次由于长度为10的哈希表已满因此在插人第11个记录时所需作的比较次数的期望值为10查找不成功时的平均长度为10习题 8参考答案8.1 选择题(1)B (2)A (3)D (4)C (5)B (6)A (7)B (8)C (9)A (10)C(11)D (12)C (13) C (14)D (15)C (16)B (17) D (18)C (19)B (20)D8.2填空题(1)快速归并(2) O(log2n)O(nlog2n)(3)归并(4)向上根结点(5) 1918163022(6)(7)4913275076386597(8)88(9)插入选择(每次选择最大的)(10)快速归并(11)O(1)O(nlog2n)(12)稳定(13)3(14)(15205040)(15)O(log2n)(16)O(n2)(17)冒泡排序快速排序(18)完全二叉树n/2(19)稳定不稳定(20)2(204015)8.3. 假定给定含有n个记录的文件(r1f2...rn)其相应的关键字为(k1k2...kn)则排序就是确定文件的一个序列rrr2...rn使得k1'≤k2'≤...≤kn'从而使得文件中n个记录按其对应关键字有序排列如果整个排序过程在内存中进行则排序叫内部排序假设在待排序的文件中存在两个或两个以上的记录具有相同的关键字若采用某种排序方法后使得这些具有相同关键字的记录在排序前后相对次序依然保持不变则认为该排序方法是稳定的否则就认为排序方法是不稳定的8.4.稳定的有:直接插入排序、二分法插入排序、起泡排序、归并排序和直接选择排序8.5.初始记录序列按关键字有序或基本有序时比较次数为最多8.6.设5个元素分别用abcde表示取a与b、c与d进行比较若a>bc>d(也可能是a<bc<d此时情况类似)显然此时进行了两次比较取b与d再比较若b>d则a>b>d若b<d则有c>d>b此时已进行了3次比较要使排序比较最多7次可把另外两个元素按折半检索排序插入到上面所得的有序序列中此时共需要4次比较从而可得算法共只需7次比较8.7.题目中所说的几种排序方法中其排序速度都很快但快速排序、归并排序、基数排序和Shell排序都是在排序结束后才能确定数据元素的全部序列而排序过程中无法知道部分连续位置上的最终元素而堆排序则是每次输出一个堆顶元素(即最大或最少值的元素)然后对堆进行再调整保证堆顶元素总是当前剩下元素的最大或最小的从而可知欲在一个大量数据的文件中如含有15000个元素的记录文件中选取前10个最大的元素可采用堆排序进行8.8.二分法排序8.9.void insertsort(seqlist r)  ;{ //对顺序表中记录R[0一N-1)按递增序进行插入排序&NBSP;int ij;  ;for(i=n-2;i>=0; i--) //在有序区中依次插入r[n-2]..r[0]  ;if(r[i].key>r[i+1].key) //若不是这样则r[i]原位不动 ;{  ;r[n]=r[i];j=i+l;//r[n]是哨兵 ;do{ //从左向右在有序区中查找插入位置 ;r[j-1]= r[j];//将关键字小于r[i].key的记录向右移 ;j++;  ;}whle(r[j].key r[j-1]=r[n];//将引i)插入到正确位置上 ;}//endif ;}//insertsort.  ;8.10.建立初始堆:[937 694 863 265 438 751 742129075 3011]&NBSP;&NBSP;第一次排序重建堆:[863 694 751 765 438 301 742 129 075]9378.11.在排序过程中每次比较会有两种情况出现若整个排序过程至少需作t次比较则显然会有2^t个情况由于n个结点总共有n!种不同的排列因而必须有n!种不同的比较路径于是: 2t≥n!即t≥log2n!因为log2nl=nlog2n-n/ln2+log2n/2+O(1)故有log2n!≈nlog2n从而t≧nlog2n得证8.12.依据堆定义可知:序列(1)、(2)、(4)是堆(3)不是堆从而可对其调整使之为如下的大根堆(1009580604095821020)8.13.第一趟:[265 301] [129 751] [863 937] [694 742] [076 438]&NBSP; &NBSP;第二趟:[129 265 301 751] [694 742 863 937] [076 438]&NBSP;&NBSP;第三趟:[129 265 301 694 742 751 863 937] [076 438]&NBSP;&NBSP;第四趟:[076 129 265 301 438 694 742 751 863 937]&NBSP;8.14.(1)归并排序:(1829) (2547) (1258) (1051)(18252947) (10125158)(1012182529475158)(2)快速排序:(1018251229585147)(1018251229475158)(1012182529475158)(3)堆排序:初始堆(大顶堆):(58 47512918122510)第一次调整:(51 472529181210)(58)第二次调整:(47 2925101812)(5158)第三次调整:(29 18251012)(475158)第四次调整:(25 181210)(29475158)第五次调整:(18 1012)(2529475158)第六次调整:(12 10) (182529475158)第七次调整:(1012182529475158)8.15.(1)直接插入排序序号 1 2 3 4 5 6 7 8 9 10 11 12 关键字 83 40 63 13 84 35 96 57 39 79 61 151=2 40 83 [63 13 84 35 96 57 39 79 61 15] 1=3 40 63 83 [13 84 35 96 57 39 79 61 15] 1=4 13 40 63 83 [84 3 5 96 57 39 79 61 15] I=5 13 40 63 83 84 [35 96 57 39 79 61 15] I=6 13 35 40 63 83 84 [96 57 39 79 61 15] 1=7 13 35 40 63 83 84 96 [57 39 79 61 15] 1=8 13 35 40 57 63 83 84 96 [ 39 79 61 15] 1=9 13 35 39 40 57 63 83 84 96 [79 61 15] I=10 13 35 39 40 57 63 79 83 84 96 [61 15] I=11 13 35 39 40 57 61 63 79 83 84 96 [15] 1=12 13 15 35 39 40 57 61 63 79 83 84 96 (2)直接选择排序序号 1 2 3 4 5 6 7 8 9 10 11 12 关键字 83 40 63 13 84 35 96 57 39 79 61 15i=1 13 [ 40 63 83 84 35 96 57 39 79 61 15] i=2 13 15 [63 83 84 35 96 57 39 79 61 40] i=3 13 15 35 [83 84 63 96 57 39 79 61 40] i=4 13 15 35 39 [84 63 96 57 83 79 61 40] i=5 13 15 35 39 40 [63 96 57 83 79 61 84] i=6 13 15 35 39 40 57 [96 63 83 79 61 84] i=7 13 15 35 39 40 57 61 [63 83 79 96 84] i=8 13 15 35 39 40 57 61 63 [83 79 96 84] i=9 13 15 35 39 40 57 61 63 79 183 96 84] i=10 13 15 35 39 40 57 61 63 79 83 [96 84] i=11 13 15 35 39 40 57 61 63 79 83 84 [96] (3)快速排序关键字 83 40 63 13 84 35 96 57 39 79 61 15 第一趟排序后 [15 40 63 13 61 35 79 57 39] 83 [96 84] 第二趟排序后 [13] 15 [63 40 61 35 79 57 39] 83 84 [96]第三趟排序后 13 15 [39 40 61 35 57] 63 [79] 83 84 96 第四趟排序后 13 15 [35] 39 [61 40 57] 63 79 83 84 96 第五趟排序后 13 15 35 39 [57 40] 61 63 79 83 84 96 第六趟排序后 13 15 35 39 40 [57] 61 63 79 83 84 96 第七趟排序后 13 15 35 39 40 57 61 63 79 83 84 96 (4)堆排序关键字 83 40 63 13 84 35 96 57 39 79 61 15排序成功的序列 96 84 83 79 63 61 57 40 39 35 15 13(5)归并排序关键字 83 40 63 13 84 35 96 57 39 79 61 15 第一趟排序后 [40 83] [13 63] [3584] [57 96] [39 79] [15 61]第二趟排序后 [13 40 63 83] [35 57 84 96] [15 39 61 79] 第三趟排序后 [13 35 40 57 63 83 84 96]] [15 39 61 79] 第四趟排序后 13 15 35 39 40 57 61 63 79 83 84 96。
数据结构第二版 主编殷人昆课后答案
2. 指出下列各算法的功能并求出其时间复杂度.
1) int Prime ( int n ) {
int i = 1 ;
int x = ( int ) sqrt ( n ) ; while ( ++ i <= x ) if ( n% i == 0) break ; if ( i > x ) return 1 ; else return 0 ; } 判断n是否是一个素数, 若是则返回1, 否则返回0, 时间 复杂度为
for ( int i = 1 ; i <= n ; i++ ) for ( int j = 1 ; j<= i ; j++ ) S; A n2 C n(n+1) B n2/2 D n(n+1)/2 3
6. 下面算法的时间复杂度为B O(n). int f ( unsigned int n ) { if ( n==0 || n==1 ) return 1 ; else return n*f ( n - 1 ) ; } A O(1) B O(n) C O(n2) D O(n!)
16
4)
int fun ( int n ) { int i = 1, s = 1 ; while ( s < n ) s += ++i ; return i ; }
求满足不等式1+2+3+...+i >= n的最小i值, 时间复杂 度为O(sqrt (n)) 17
5)
void UseFile (ifstream& inp, int c[10]) {
Quadratic InitQuadratic(float aa=0, float bb=0, float cc=0); Quadratic InitQuadratic( float aa, float bb, float cc ) { Quadratic q ; q.a = aa ; q.b = bb ; q.c = cc ; return q ; }
《数据结构》第三章习题参考答案 殷人昆版
《数据结构》第三章习题参考答案殷人昆版,《数据结构》第三章习题参考答案一、判断题(在正确说法的题后括号中打“√”,错误说法的题后括号中打“×”)1、栈和队列都是线性表,只是在插入和删除时受到了一些限制。
( √ )2、循环队列也存在空间溢出问题。
( √ )3、任何一个递归过程都可以转换成非递归过程。
( √ )4、消除递归不一定需要使用栈。
( √ )5、有n个数顺序(依次)进栈,出栈序列有Cn种,Cn=(1/(n+1))*(2n)!/((n!)*(n!))。
(√ )6、循环队列方式能很好地解决队列的假溢出现象。
(√ )二、单项选择题1、1.设有一个顺序栈S,元素P1,P2,P3,P4,P5,P6依次进栈,得到的出栈顺序P2,P3,P4,P6,P5,P1,则顺序栈的容量至少为( B )。
A.2 B.3 C.4D.无法确定2.一个队列的输出序列是1,2,3,4,则队列的入队序列是( A )。
A.1,2,3,4 B.1,4,3,2 C.4,3,2,1 D.不确定3、对于一个循环队列(最大元素个数为maxSize)进行入队操作时,对队列指针的修改正确的语句是( C )。
A.rear = rear + 1 B.front = front + 1C.rear = (rear + 1)% maxSize D.front = (front + 1)% maxSize4、假设以数组A[m]存放循环队列的元素,其头尾指针分别为front和rear,则当前队列中的元素个数为( A )。
A.(rear-front+m)%m B.rear-front+1 C.(front-rear+m)%m D.(rear-front)%m5、表达式a*(b+c)-d的后缀表达式是( B )。
A.abcd*+- 表达式[a-(c*d+b)] B. abc+*d- C. abc*+d- 表达式b*c+a-d D. -+*abcd6、若用一个大小为6的数组来实现循环队列,且当前rear和front的值分别为0和3,当从队列中删除一个元素,再加入两个元素后,rear和front的值分别为多少?( B )A. 1和 5B. 2和4C. 4和2D. 5和17、设abcdef以所给的次序进栈,若在进栈操作时,允许退栈操作,则下面得不到的序列为( D )。
数据结构c殷人昆第二版答案
数据结构c殷人昆第二版答案【篇一:《数据结构》第四章习题参考答案】1、kmp算法的特点是在模式匹配时指示主串的指针不会变小。
( √ )2、串是一种数据对象和操作都特殊的线性表。
( √)5、使用三元组表示稀疏矩阵的非零元素能节省存储空间。
( √)6、插入与删除操作是数据结构中最基本的两种操作,因此这两种操作在数组中7、若采用三元组表存储稀疏矩阵,只要把每个元素的行下标和列下标互换(错二、单项选择题1.下面关于串的的叙述中,哪一个是不正确的?( b )a.串是字符的有限序列 b.空串是由空格构成的串(空串是长度为零的串)c.模式匹配是串的一种重要运算d.串既可以采用顺序存储,也可以采用链式存储2.有串s1=’abcdefg’,s2 = ’pqrst’,假设函数con(x,y)返回x和y串的连接串,subs(s,i,j)返回串s的从序号i的字符开始的j个字符组成的子串,len(s)返回中s的长度,则con(subs(s1,2,len(s2)),subs(s1,len(s2),2))的结果串是( d )。
a.bcdef b.bcdefg c.bcpqrst d.cdefgfg3、串的长度是指( b )a.串中所含不同字母的个数 b.串中所含字符的个数c.串中所含不同字符的个数 d.串中所含非空格字符的个数三、填空题1、串是一种特殊的线性表,其特殊性表现在_数据元素为字符,操作集也不同__;串的两种最基本的存储方式是_顺序存储 _、__ 链式存储 _;两个串相等的充分必要条件是__两串的长度相等且两串中对应位置的字符也相等__。
2、设正文串长度为n,模式串长度为m,则串匹配的kmp算法的时间复杂度为_o(m+n)__。
3、模式串p=‘abaabcac’的next函数值序列为___。
4、已知数组a[0..9,0..9]的每个元素占5个存储单元,将其按行优先次序存储在起始地址为1000的连续的内存单元中,则元素a[6,8]的地址为__1340___。
(完整版) 《数据结构》教材课后习题+答案
第1章绪论习题1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
3.简述逻辑结构的四种基本关系并画出它们的关系图。
4.存储结构由哪两种基本的存储方法实现?5.选择题(1)在数据结构中,从逻辑上可以把数据结构分成()。
A.动态结构和静态结构B.紧凑结构和非紧凑结构C.线性结构和非线性结构D.内部结构和外部结构(2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的()。
A.存储结构B.存储实现C.逻辑结构D.运算实现(3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着()。
A.数据具有同一特点B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致C.每个数据元素都一样D.数据元素所包含的数据项的个数要相等(4)以下说法正确的是()。
A.数据元素是数据的最小单位B.数据项是数据的基本单位C.数据结构是带有结构的各数据项的集合D.一些表面上很不相同的数据可以有相同的逻辑结构(5)以下与数据的存储结构无关的术语是()。
A.顺序队列 B. 链表 C. 有序表 D. 链栈(6)以下数据结构中,()是非线性数据结构A.树B.字符串C.队D.栈6.试分析下面各程序段的时间复杂度。
(1)x=90; y=100;while(y>0)if(x>100){x=x-10;y--;}else x++;(2)for (i=0; i<n; i++)for (j=0; j<m; j++)a[i][j]=0;(3)s=0;for i=0; i<n; i++)for(j=0; j<n; j++)s+=B[i][j];sum=s;(4)i=1;while(i<=n)i=i*3;(5)x=0;for(i=1; i<n; i++)for (j=1; j<=n-i; j++)x++;(6)x=n; //n>1y=0;while(x≥(y+1)* (y+1))y++;(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)(5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2)(6)O(n)第2章线性表1.选择题(1)一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是()。
《数据结构》第二章习题参考答案殷人昆版
《数据结构》第二章习题参考答案一、判断题(在正确说法的题后括号中打“√”,错误说法的题后括号中打“×”)1、顺序存储方式插入和删除时效率太低,因此它不如链式存储方式好。
( × )2、链表中的头结点仅起到标识的作用。
( × )3、所谓静态链表就是一直不发生变化的链表。
( × )4、线性表的特点是每个元素都有一个前驱和一个后继。
( × )5、在顺序表中,逻辑上相邻的元素在物理位置上不一定相邻。
(×)6、线性表就是顺序存储的表。
(×)7、课本P84 2.4题(1)√(2)×(3)×(4)×(5)√(6)×(7)×(8)√(9)×(10)×(11)√(12)√二、单项选择题1、下面关于线性表的叙述中,错误的是哪一个?( B )A.线性表采用顺序存储,必须占用一片连续的存储单元。
B.线性表采用顺序存储,便于进行插入和删除操作。
C.线性表采用链接存储,不必占用一片连续的存储单元。
D.线性表采用链接存储,便于插入和删除操作。
2、链表不具有的特点是( B )A.插入、删除不需要移动元素B.可随机访问任一元素C.不必事先估计存储空间D.所需空间与线性长度成正比3、(1) 静态链表既有顺序存储的优点,又有动态链表的优点。
所以,它存取表中第i个元素的时间与i无关。
(2) 静态链表中能容纳的元素个数的最大数在表定义时就确定了,以后不能增加。
(3) 静态链表与动态链表在元素的插入、删除上类似,不需做元素的移动。
以上错误的是( B )A.(1),(2)B.(1)C.(1),(2),(3) D.(2)4、在单链表指针为p的结点之后插入指针为s的结点,正确的操作是(B)A.p->link =s; s-> link =p-> link; B.s-> link =p-> link; p-> link =s; C.p-> link =s; p-> link =s-> link; D.p-> link =s-> link; p-> link =s;5、若某线性表最常用的操作是取任一指定序号的元素及其前驱,则利用(C)存储方式最节省时间。
清华殷人昆(C++)数据结构考研辅导教程-第1章
1.2.1 数据结构的主要概念
1.什么是数据 数据是信息的载体,是描述客观事物的数、字符、以及所有能输入到计算机中,被计算 机程序识别和处理的符号的集合。 数据主要分两大类:数值性数据和非数值性数据。数据结构主要研究的是非数值型数据。 2.什么是数据元素 数据的基本单位就是数据元素。例如,在学校的学籍管理系统中学生文件是由一系列学 生记录组成,每个学生记录就是一个数据元素。在计算机程序中数据元素常作为一个整 体进行考虑和处理。数据元素又可称为元素、结点、记录。 有时一个数据元素可以由若干数据项组成。数据项是具有独立含义的最小标识单位。例 如,每个学生记录又可由学号、姓名、性别等数据项组成。 数据元素的集合构成一个数据对象,它是针对某种特定的应用。 3.什么是数据结构 数据结构指某一数据元素集合中的所有数据成员之间的关系。完整的定义为:
1.2.2 算法及算法分析
1.算法的概念 所谓算法,就是基于特定的计算模型在信息处理过程中为了解决某一类问题而设计的一 个指令序列。算法的 5 个要素是 有输入:待处理的信息,即用数据对具体问题的描述; 有输出:经过处理后得到的信息,即问题的答案; 确定性:对于相同的输入数据,算法执行确定的预设路线,得到确定的结果; 可行性:算法的每一基本操作都可以实施,并能够在常数时间内完成; 有穷性:对于任何输入,算法都能经过有穷次基本操作得到正确的结果。 2.设计算法的三个阶段 设计算法通常经过三个主要阶段 (1) 从问题出发,寻找可能的解决方案,结合计算机选择合适的算法; (2) 建立解决问题的数据模型和程序框架,并用伪代码描述一系列步骤;
-2-
(7) 堆排序的思路、算法和性能分析、稳定性 (8) 二路归并排序的思路、算法和性能分析(已考)、稳定性 (9) 基数排序的思路、算法和性能分析 (10) 排序方法的性能比较(已考) (11) 排序方法的应用 在复习过程要切实掌握这些知识点,才能够对考试应付自如。复习方法参看第 8 章。
数据结构-清华大学-殷人昆-05
138-28
对于带权图还需设置一个存放与该边相关的权 值的域 cost。
顶点结点的结构
data Firstout
向的。
138-3
有向图与无向图 在有向图中,顶点对 <x, y> 是 有序的。在无向图中,顶点对(x, y)是无序的。
完全图 若有 n 个顶点的无向图有 n(n-1)/2 条边, 则此图为完全无向图。有 n 个顶点的有向图有 n(n-1) 条边, 则此图为完全有向图。
0
0
00
1
121 2
1
//最大顶点个数
typedef char VType;
//顶点数据类型
typedef int WType;
//边上权值类型
typedef struct {
//静态存储定义
VType verticesList[maxVertices]; //顶点表
WType Edge[maxVertices][maxVertices];
138-8
图的存储表示
邻接矩阵 (Adjacency Matrix)
在图的邻接矩阵表示中,有一个记录各个顶点信 息的顶点表,还有一个表示各个顶点之间关系的 邻接矩阵。
设图 A = (V, E)是一个有 n 个顶点的图, 图的邻接 矩阵是一个二维数组 A.edge[n][n],定义:
A.Edge[
if ( v != -1 ) { for ( int col = 0; col < G.numVertices; col++ ) if ( G.Edge[v][col] > 0 && G.Edge[v][col] < maxValue ) return col; //顺序检测第 v 行寻找第一个邻接顶点 //对于无权图,maxValue应为INT_MAX
数据结构课后习题答案清华大学出版社殷人昆
}
friend ostream& operator<< (ostream&os, complex&ob ){
//友元函数:重载<<,将复数ob输出到输出流对象os中。
returnos << ob.Re << ( ob.Im >= 0.0 )?“+” : “-” <<fabs( ob.Im ) << “i”;
1-2什么是数据结构?有关数据结构的讨论涉及哪三个方面?
【解答】
数据结构是指数据以及相互之间的关系。记为:数据结构={D, R}。其中,D是某一数据对象,R是该对象中所有数据成员之间的关系的有限集合。
有关数据结构的讨论一般涉及以下三方面的内容:
1数据成员以及它们相互之间的逻辑关系,也称为数据的逻辑结构,简称为数据结构;
}
1-5用归纳法证明:
(1)
(2)
(3)
【证明】略
1-6什么是算法?算法的5个特性是什么?试根据这些特性解释算法与程序的区别。
【解答】
通常,定义算法为“为解决某一特定任务而规定的一个指令序列。”一个算法应当具有以下特性:
①有输入。一个算法必须有0个或多个输入。它们是算法开始运算前给予算法的量。这些输入取自于特定的对象的集合。它们可以使用输入语句由外部提供,也可以使用赋值语句在算法内给定。
doublegetReal ( ){ returnRe; }//取复数实部
doublegetImag ( ){ returnIm; }//取复数虚部
voidsetReal (doubler ){Re = r; }//修改复数实部
(完整版) 《数据结构》教材课后习题+答案
第1章绪论习题1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
2.试举一个数据结构的例子,叙述其逻辑结构和存储结构两方面的含义和相互关系。
3.简述逻辑结构的四种基本关系并画出它们的关系图。
4.存储结构由哪两种基本的存储方法实现?5.选择题(1)在数据结构中,从逻辑上可以把数据结构分成()。
A.动态结构和静态结构B.紧凑结构和非紧凑结构C.线性结构和非线性结构D.内部结构和外部结构(2)与数据元素本身的形式、内容、相对位置、个数无关的是数据的()。
A.存储结构B.存储实现C.逻辑结构D.运算实现(3)通常要求同一逻辑结构中的所有数据元素具有相同的特性,这意味着()。
A.数据具有同一特点B.不仅数据元素所包含的数据项的个数要相同,而且对应数据项的类型要一致C.每个数据元素都一样D.数据元素所包含的数据项的个数要相等(4)以下说法正确的是()。
A.数据元素是数据的最小单位B.数据项是数据的基本单位C.数据结构是带有结构的各数据项的集合D.一些表面上很不相同的数据可以有相同的逻辑结构(5)以下与数据的存储结构无关的术语是()。
A.顺序队列 B. 链表 C. 有序表 D. 链栈(6)以下数据结构中,()是非线性数据结构A.树B.字符串C.队D.栈6.试分析下面各程序段的时间复杂度。
(1)x=90; y=100;while(y>0)if(x>100){x=x-10;y--;}else x++;(2)for (i=0; i<n; i++)for (j=0; j<m; j++)a[i][j]=0;(3)s=0;for i=0; i<n; i++)for(j=0; j<n; j++)s+=B[i][j];sum=s;(4)i=1;while(i<=n)i=i*3;(5)x=0;for(i=1; i<n; i++)for (j=1; j<=n-i; j++)x++;(6)x=n; //n>1y=0;while(x≥(y+1)* (y+1))y++;(1)O(1)(2)O(m*n)(3)O(n2)(4)O(log3n)(5)因为x++共执行了n-1+n-2+……+1= n(n-1)/2,所以执行时间为O(n2)(6)O(n)第2章线性表1.选择题(1)一个向量第一个元素的存储地址是100,每个元素的长度为2,则第5个元素的地址是()。
殷人昆数据结构习题解答第2章习题
作为抽象数据类型数组的类声明。
#include <iostream.h> //在头文件“array.h”中#include <stdlib.h>const int DefaultSize = 30;template <class Type> class Array {//数组是数据类型相同的n(size)个元素的一个集合, 下标范围从0到n-1。
对数组中元素//可按下标所指示位置直接访问。
private:Type *elements; //数组int ArraySize; //元素个数public:Array ( int Size = DefaultSize ); //构造函数Array ( const Array<Type> & x ); //复制构造函数~Array ( ) { delete [ ] elements; } //析构函数Array<Type>&operator = ( const Array<Type>& A ); //数组整体赋值(复制)Type& operator [ ] ( int i ); //按下标访问数组元素int Length ( ) const { return ArraySize; } //取数组长度void ReSize ( int sz ); //修改数组长度}顺序表的类定义#include < iostream.h> //定义在头文件“seqlist.h”中#include <stdlib.h>template <class Type> class SeqList {private:Type *data; //顺序表的存放数组int MaxSize; //顺序表的最大可容纳项数int last; //顺序表当前已存表项的最后位置int current; //顺序表的当前指针(最近处理的表项)public:SeqList ( int MaxSize ); //构造函数~SeqList ( ) { delete [ ] data; } //析构函数int Length ( ) const{ return last+1;} //计算表长度int Find ( Type& x ) const; //定位函数:找x在表中位置,置为当前表项int IsIn ( Type& x ); //判断x是否在表中,不置为当前表项Type *GetData ( ) { return current == -1?NULL : data[current]; } //取当前表项的值int Insert ( Type& x ); //插入x在表中当前表项之后,置为当前表项int Append ( Type& x ); //追加x到表尾,置为当前表项Type * Remove ( Type& x ); //删除x,置下一表项为当前表项Type *First ( ); //取表中第一个表项的值,置为当前表项Type *Next ( ) {return current < last ? &data[++current] : NULL; }//取当前表项的后继表项的值,置为当前表项//取当前表项的前驱表项的值,置为当前表项int IsEmpty ( ) { return last == -1;} //判断顺序表空否, 空则返回1; 否则返回0int IsFull ( ) { return last == MaxSize-1;} //判断顺序表满否, 满则返回1; 否则返回0 }2-1 设n个人围坐在一个圆桌周围,现在从第s个人开始报数,数到第m个人,让他出局;然后从出局的下一个人重新开始报数,数到第m个人,再让他出局,……,如此反复直到所有的人全部出局为止。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1-1什么是数据? 它与信息是什么关系?【解答】什么是信息?广义地讲,信息就是消息。
宇宙三要素(物质、能量、信息)之一。
它是现实世界各种事物在人们头脑中的反映。
此外,人们通过科学仪器能够认识到的也是信息。
信息的特征为:可识别、可存储、可变换、可处理、可传递、可再生、可压缩、可利用、可共享。
什么是数据?因为信息的表现形式十分广泛,许多信息在计算机中不方便存储和处理,例如,一个大楼中4部电梯在软件控制下调度和运行的状态、一个商店中商品的在库明细表等,必须将它们转换成数据才能很方便地在计算机中存储、处理、变换。
因此,数据(data)是信息的载体,是描述客观事物的数、字符、以及所有能输入到计算机中并被计算机程序识别和处理的符号的集合。
在计算机中,信息必须以数据的形式出现。
1-2什么是数据结构? 有关数据结构的讨论涉及哪三个方面?【解答】数据结构是指数据以及相互之间的关系。
记为:数据结构= { D, R }。
其中,D是某一数据对象,R是该对象中所有数据成员之间的关系的有限集合。
有关数据结构的讨论一般涉及以下三方面的内容:①数据成员以及它们相互之间的逻辑关系,也称为数据的逻辑结构,简称为数据结构;②数据成员极其关系在计算机存储器内的存储表示,也称为数据的物理结构,简称为存储结构;③施加于该数据结构上的操作。
数据的逻辑结构是从逻辑关系上描述数据,它与数据的存储不是一码事,是与计算机存储无关的。
因此,数据的逻辑结构可以看作是从具体问题中抽象出来的数据模型,是数据的应用视图。
数据的存储结构是逻辑数据结构在计算机存储器中的实现(亦称为映像),它是依赖于计算机的,是数据的物理视图。
数据的操作是定义于数据逻辑结构上的一组运算,每种数据结构都有一个运算的集合。
例如搜索、插入、删除、更新、排序等。
1-3数据的逻辑结构分为线性结构和非线性结构两大类。
线性结构包括数组、链表、栈、队列、优先级队列等; 非线性结构包括树、图等、这两类结构各自的特点是什么?【解答】线性结构的特点是:在结构中所有数据成员都处于一个序列中,有且仅有一个开始成员和一个终端成员,并且所有数据成员都最多有一个直接前驱和一个直接后继。
例如,一维数组、线性表等就是典型的线性结构非线性结构的特点是:一个数据成员可能有零个、一个或多个直接前驱和直接后继。
例如,树、图或网络等都是典型的非线性结构。
1-4.什么是抽象数据类型?试用C++的类声明定义“复数”的抽象数据类型。
要求(1) 在复数内部用浮点数定义它的实部和虚部。
(2) 实现3个构造函数:缺省的构造函数没有参数;第二个构造函数将双精度浮点数赋给复数的实部,虚部置为0;第三个构造函数将两个双精度浮点数分别赋给复数的实部和虚部。
(3) 定义获取和修改复数的实部和虚部,以及+、-、*、/等运算的成员函数。
(4) 定义重载的流函数来输出一个复数。
【解答】抽象数据类型通常是指由用户定义,用以表示应用问题的数据模型。
抽象数据类型由基本的数据类型构成,并包括一组相关的服务。
//在头文件complex.h中定义的复数类#ifndef _complex_h_#define _complex_h_#include <iostream.h>class comlex {public:complex ( ){ Re = Im = 0; }//不带参数的构造函数complex ( double r ) { Re = r;Im = 0; }//只置实部的构造函数complex ( double r, double i ) { Re = r;Im = i; }//分别置实部、虚部的构造函数double getReal ( ) { return Re; }//取复数实部double getImag ( ) { return Im; }//取复数虚部void setReal ( double r ) { Re = r; }//修改复数实部void setImag ( double i ) { Im = i; } //修改复数虚部complex& operator = ( complex& ob) { Re = ob.Re;Im = ob.Im; }//复数赋值complex& operator + ( complex& ob );//重载函数:复数四则运算complex& operator– ( complex& ob );complex& operator * ( complex& ob );complex& operator / ( complex& ob );friend ostream& operator << ( ostream& os, complex& c );//友元函数:重载<<private:double Re, Im; //复数的实部与虚部};#endif//复数类complex的相关服务的实现放在C++源文件complex.cpp中#include <iostream.h>#include <math.h>#include“complex.h”complex& complex :: operator + ( complex & ob ) {//重载函数:复数加法运算。
complex * result = new complex ( Re + ob.Re, Im + ob.Im );return *result;}complex& complex :: operator– ( complex& ob ) {//重载函数:复数减法运算complex * result = new complex ( Re – ob.Re, Im – ob.Im );return * result;}1n ,21)n(n i n1i ≥+=∑=complex & complex :: operator * ( complex & ob ) { //重载函数:复数乘法运算complex * result =new complex ( Re * ob.Re – Im * ob.Im, Im * ob.Re + Re * ob.Im );return *result ;}complex & complex :: operator / ( complex & ) { //重载函数:复数除法运算double d = ob.Re * ob.Re + ob.Im * ob.Im ;complex * result = new complex ( ( Re * ob.Re + Im * ob.Im ) / d,( Im * ob. Re – Re * ob.Im ) / d ); return * result ;}friend ostream& operator << ( ostream& os, complex & ob ) { //友元函数:重载<<,将复数ob 输出到输出流对象os 中。
return os << ob.Re << ( ob.Im >= 0.0 ) ? “+” : “-” << fabs ( ob.Im ) << “i”;}1-5 用归纳法证明:(1) (2) 1n ,61)1)(2n n(n in1i 2≥++=∑=(3)0n 1, x ,1x 1x x 1n ni i≥≠--=+=∑ 【证明】略1-6 什么是算法? 算法的5个特性是什么? 试根据这些特性解释算法与程序的区别。
【解答】 通常,定义算法为“为解决某一特定任务而规定的一个指令序列。
”一个算法应当具有以下特性: ① 有输入。
一个算法必须有0个或多个输入。
它们是算法开始运算前给予算法的量。
这些输入取自于特定的对象的集合。
它们可以使用输入语句由外部提供,也可以使用赋值语句在算法内给定。
② 有输出。
一个算法应有一个或多个输出,输出的量是算法计算的结果。
③ 确定性。
算法的每一步都应确切地、无歧义地定义。
对于每一种情况,需要执行的动作都应严格地、清晰地规定。
④ 有穷性。
一个算法无论在什么情况下都应在执行有穷步后结束。
⑤ 有效性。
算法中每一条运算都必须是足够基本的。
就是说,它们原则上都能精确地执行,甚至人们仅用笔和纸做有限次运算就能完成。
算法和程序不同,程序可以不满足上述的特性(4)。
例如,一个操作系统在用户未使用前一直处于“等待”的循环中,直到出现新的用户事件为止。
这样的系统可以无休止地运行,直到系统停工。
此外,算法是面向功能的,通常用面向过程的方式描述;程序可以用面向对象方式搭建∑∑∑====n 1i n 1j 3n1k n 162)1)(n n(n 21)n(n 2161)1)(2n n(n 21 i 21i 2121)i(i j 1n1i n1i n 1i 2n 1i i 1j n 1i i 1j j 1k ++=++++==+=⎪⎭⎫ ⎝⎛+==∑∑∑∑∑∑∑∑========⎪⎭⎫⎝⎛++=++⎪⎭⎫ ⎝⎛++=+⎪⎭⎫ ⎝⎛++==++=+==∑∑==21)n(n 2121)n(n 21)n(n 1j 21)n(n 1i 时, 2i 21)n(n 1j 1i 时 1i n 1j n1j ,⎪⎭⎫⎝⎛++=+⎪⎪⎭⎫ ⎝⎛⎪⎭⎫ ⎝⎛++==∑=21)n(n 31j 21)n(n 21i 时, 3i n 1j 它的框架。
1-7 设n 为正整数, 分析下列各程序段中加下划线的语句的程序步数。
(1) for (int i = 1; i <= n ; i++) (2) x = 0; y = 0; for (int j = 1; j <= n ; j++) { for (int i = 1; i <= n ; i++) c[i][j] = 0.0; for (int j = 1; j <= i ; j++) for (int k = 1; k <= n ; k++) for (int k = 1; k <= j ; k++) c[i][j] = c[i][j] + a[i][k] * b[k][j]; x = x + y ; } (3) int i = 1, j = 1; (4) int i =1; while (i<=n && j<=n) { do { i = i + 1; j = j + i ; for (int j = 1; j <= n ; j++) } i = i + j ; } while ( i < 100 + n );【解答】(1) (2)(3) i = 1时,i = 2,j = j + i = 1 + 2 = 2 + 1,i = 2时,i = 3,j = j + i = ( 2 + 1 ) + 3 = 3 + 1 + 2,i = 3时,i = 4,j = j + i = ( 3 + 1 + 2 ) + 4 = 4 + 1 + 2 + 3,i = 4时,i = 5,j = j + i = ( 4 + 1 + 2 + 3 ) + 5 = 5 + 1 + 2 + 3 + 4, ……i = k 时,i = k + 1,j = j + i = ( k + 1 ) + ( 1 + 2 + 3 + 4 + … + k ),解出满足上述不等式的k 值,即为语句i = i + 1的程序步数。