C14068课后测验
微型计算机技术课后习题一二三章答案
微计算机二三章1.已知物理地址为FFFF0H,且段内偏移量为A000H,若对应的段地址放在DS中,则DS应为(B) 。
A.5FFFHB.F5FFHC.5FFF0HD.F5FF0H2.下列CPU中属于准16位的是C 。
A.8080B.8086C.8088D.80386SX3.8088的外部数据总线为 A 位。
A.8B.16C.32D.644.8086CPU的内部结构由 D 组成。
A.ALU,EU,BIUB.ALU,BIU,地址加法器C.寄存器组,ALUD.EU,BIU5.每当8086的指令队列中有B空字节,BIU就会自动把指令取到指令队列中。
A.1个B.2个C.3个D.4个6.BIU的功能是C。
A.计算有效地址B.分析指令,产生控制信号C.与存储器或I/O端口之间进行传送,并能形成物理地址D.进行算术运算与逻辑运算7.指令队列缓冲器的作用是 D 。
A.暂存操作数地址B.暂存操作数C.暂存指令地址D.暂存预取指令8.8086的指令队列的长度是 C 字节。
A.4个B.5个C.6个D.8个9.8088的指令队列的长度是A字节。
A.4个B.5个C.6个D.8个10.下列寄存器都存在于BIU部件的是B。
A.SP、CSB.IP、DSC.BP、IPD.FR、SP11.8086 CPU内部共有 C 个16位寄存器。
A.12B.13C.14D.1612.不属于EU部分的寄存器是A 。
A.IPB.BPC.DID.SP13.8086/8088的状态标志有D个。
A.3B.4C.5D.614.8086有B个地址/数据复用引脚。
A.8B.16C.20D.3215.8088有 A 个地址/数据复用引脚。
A.8B.16C.20D.3216.8086/8088中,一个最基本的总线周期由 B 个时钟周期(T状态)组成。
A.1B.4C.2D.617.在8086/8088中,在T1状态,CPU往总线发出C信号。
A.数据B.状态C.地址D.其它18.总线周期为T1、T2、T3、T4,若要增加等待状态T W,它应插在C之后。
数据结构(C语言版)第2版习题答案—严蔚敏(简化版)
数据结构(C语言版)第2版习题答案—严蔚敏(简化版)第2章线性表i ?选择题(i )顺序表中第一个元素的存储地址是的地址是()OA ? 110B ? 108答案:B解释:顺序表中的数据连续存储,所以第100 ,每个元素的长度为 2 ,则第5个元素C ? 100D ? 1205个元素的地址为:100+2*4=108 O(3 )向一个有127个元素的顺序表中插入一个新元素并保持原来顺序不变,平均要移动_的元素个数为()。
A ? 8B ? 63.5C ? 63D . 7答案:B解释:平均要移动的元素个数为:n/2 O(4)链接存储的存储结构所占存储空间()°A ?分两部分,一部分存放结点值,另一部分存放表示结点间关系的指针B ?只有一部分,存放结点值C ?只有一部分,存储表示结点间关系的指针D ?分两部分,一部分存放结点值,另一部分存放结点所占单元数答案:A(5 )线性表若采用链式存储结构时,要求内存中可用存储单元的地址()。
A .必须是连续的 C ?一定是不连续的答案:DC ?L 中含有大量的结点D.L 中结点结构复杂答案:B解释:链表最大的优点在于插入和删除时不需要移动数据,直接修改指针即可。
(7 )单链表的存储密度()A ?大于1B ?等于1C ?小于1D ?不能确定答案:C解释:存储密度是指一个结点数据本身所占的存储空间和整个结点所占的存储空间之比,假设单链表一个结点本身所占的空间为 D ,指针域所占的空间为 N ,则存储密度为:D/(D+N ),—定小于1 °(8)将两个各有 n 个元素的有序表归并成一个有序表,其最少的比较次数是()°答案:A解释:当第一个有序表中所有的元素都小于(或大于)第二个表中的元素,只需要用第二个表中的B ?部分地址必须是连续的 D ?连续或不连续都可以(6)线性表1在()情况下适用于使用链式结构实现。
A ?需经常修改L 中的结点值E.需不断对L 进行删除插入 B ? 2n-1 C ? 2n D ? n-1第一个元素依次与第一个表的元素比较,总计比较n次。
程序设计基础c语言邹启明综合练习题答案
程序设计基础c语言邹启明综合练习题答案1.下列不是C语言特点的是()。
[单选题] *A.C语言简洁、紧凑B.比较难学(正确答案)C可以直接对硬件进行操作D.C语言移植性好2.计算机最基本的操作单元不包括()。
[单选题] *A.位B.字节C.地址D.元组(正确答案)3.计算机唯一能识别的语言是()。
[单选题] *A.机器语言(正确答案)B.汇编语言C高级语言D.面向对象语言4.下列说法错误的是()。
[单选题] *A.C语言程序由若干个函数组成B.C语言是一种结构化程序设计语言C.C语言包含的数据类型不多(正确答案)D.C语言的语法限制不太严格5.下面对C语言特点的描述不正确的是()。
[单选题] *A.C语言兼有高级语言和低级语言的双重特点,执行效率高B.C语言既可以用来编写应用程序,又可以用来编写系统软件C.C语言中的变量可以不定义,直接使用(正确答案)D.C语言是一种结构化设计语言6.下列不是C语言中的关键字的是()。
[单选题] *A.caseB.typedefC.staticD.null(正确答案)7.二进制语言属于()。
[单选题] *A.面向机器语言(正确答案)B.面向过程语言C.面向问题语言D.面向汇编语言8.C语言具有低级语言的功能,主要是指()。
[单选题] *A.程序的可移植性B.程序的使用方便性C.能直接访问物理地址,可进行位操作(正确答案)D.具有现代化语言的各种数据结构9.C语言程序能够在不同的操作系统下运行这说明C语言具有很好的()。
[单选题] *A.适应性B.兼容性C.移植性(正确答案)D.操作性10. ()用符号来替代二进制序列。
[单选题] *A.机器语言B.汇编语言(正确答案)C.高级语言D.自然语言11.1983年,为C语言制定了一套标准,成为现行的C语言标准。
()。
[单选题] *A.ISOB.NSFC.CITTD.ANSI(正确答案)12.C语言一共有个关键字。
数据结构c语言版严蔚敏习题答案
数据结构c语言版严蔚敏习题答案数据结构是计算机科学中非常重要的一门课程,它研究的是数据的组织、存储和管理方式。
而C语言是一种被广泛应用于系统编程和嵌入式开发的编程语言。
在学习数据结构的过程中,很多人会选择使用严蔚敏编写的《数据结构(C语言版)》一书。
本文将针对该书中的习题,为大家提供一些答案和解析。
1. 顺序表顺序表是一种使用连续的内存空间来存储数据的数据结构。
在《数据结构(C语言版)》一书中,我们可以通过使用结构体来实现顺序表。
下面是一个示例代码:```c#include <stdio.h>#include <stdlib.h>#define MAXSIZE 100typedef struct {int data[MAXSIZE];int length;} SqList;void InitList(SqList *L) {L->length = 0;}void Insert(SqList *L, int pos, int value) {if (L->length >= MAXSIZE) {printf("顺序表已满,无法插入!"); return;}if (pos < 1 || pos > L->length + 1) { printf("插入位置非法!");return;}for (int i = L->length; i >= pos; i--) { L->data[i] = L->data[i - 1];}L->data[pos - 1] = value;L->length++;}void Delete(SqList *L, int pos) {if (pos < 1 || pos > L->length) {printf("删除位置非法!");return;}for (int i = pos - 1; i < L->length - 1; i++) { L->data[i] = L->data[i + 1];}L->length--;}int main() {SqList L;InitList(&L);Insert(&L, 1, 10);Insert(&L, 2, 20);Insert(&L, 3, 30);Delete(&L, 2);for (int i = 0; i < L.length; i++) {printf("%d ", L.data[i]);}return 0;}2. 链表链表是一种使用非连续的内存空间来存储数据的数据结构。
数据结构习题集答案(C语言版严蔚敏) (1)
#include<iostream.h> #include<stdlib.h> #define MAXINT 65535 #define ArrSize 100 int fun(int i); int main() { int i,k; int a[ArrSize]; cout<<"Enter k:"; cin>>k; if(k>ArrSize-1) exit(0); for(i=0;i<=k;i++){ if(i==0) a[i]=1; else{ if(2*i*a[i-1]>MAXINT) exit(0); else a[i]=2*i*a[i-1]; } } for(i=0;i<=k;i++){ if(a[i]>MAXINT) exit(0); else cout<<a[i]<<" "; } return 0; } 1.20 试编写算法求ห้องสมุดไป่ตู้元多项式的值的值,并确定算法中每一语句的执 行次数和整个算法的时间复杂度。注意选择你认为较好的输入和输出 方法。本题的输入为,和,输出为。 解: #include<iostream.h> #include<stdlib.h> #define N 10 double polynomail(int a[],int i,double x,int n); int main() { double x;
ADT Complex{ 数据对象:D={r,i|r,i为实数} 数据关系:R={<r,i>} 基本操作: InitComplex(&C,re,im) 操作结果:构造一个复数C,其实部和虚部分别为re和im DestroyCmoplex(&C) 操作结果:销毁复数C Get(C,k,&e) 操作结果:用e返回复数C的第k元的值 Put(&C,k,e) 操作结果:改变复数C的第k元的值为e IsAscending(C) 操作结果:如果复数C的两个元素按升序排列,则返回 1,否则返回0 IsDescending(C) 操作结果:如果复数C的两个元素按降序排列,则返回 1,否则返回0 Max(C,&e) 操作结果:用e返回复数C的两个元素中值较大的一个 Min(C,&e) 操作结果:用e返回复数C的两个元素中值较小的一个 }ADT Complex ADT RationalNumber{ 数据对象:D={s,m|s,m为自然数,且m不为0} 数据关系:R={<s,m>} 基本操作: InitRationalNumber(&R,s,m) 操作结果:构造一个有理数R,其分子和分母分别为s和m DestroyRationalNumber(&R) 操作结果:销毁有理数R Get(R,k,&e) 操作结果:用e返回有理数R的第k元的值 Put(&R,k,e) 操作结果:改变有理数R的第k元的值为e IsAscending(R)
C语言程序设计答案-(陈明晰)中国铁道出版社
习题一一、选择题1.C程序的基本单位是(A)。
A.函数B.文件C.语句D.字符2.C程序中的变量(B)。
A.不用说明B.先说明后引用C.先引用后说明D.引用和说明顺序无关3.变量的说明在(B)。
A.执行语句之后B.执行语句之前C.执行语句当中D.位置无关4.C语言是一种(C)。
A.机器语言B.符号语言C.高级语言D.面向对象的语言二、填空题1.一个C程序总是从主函数开始执行。
2.结构化程序由顺序、选择、循环三种基本结构构成。
3.一个C程序只有一个名为main的主函数。
4.C程序中的每个语句以分号结束。
5.C程序中,函数由函数首部和函数体组成。
6.每个基本结构有一个入口和一个出口,没有死循环和死语句。
7.算法是计算机解决问题所依据的步骤。
习题二一、选择题1.下列数据中属于字符串常量的是( B)。
A.ABC B."ABC" C.'abc' D.'A'2.在计算机内存中,'\n'占用的字节数是( C)。
A.4 B.3 C.1 D.23.字符串"ABC"在内存中占用的字节数是( D)。
A.6 B.8 C.3 D.44.在C语言中,合法的长整型常数是( B)。
A.568701400 B.0L C.0.03546287D.2.654e115.char型常量在内存中存放的是( A)。
A.ASCII代码值B.BCD代码值C.十进制代码值D.内码值6.下列各项中正确的标识符是( D)。
A.?bb B.a=8 C. b.βD.b_47.下列不正确的转义字符是( D)。
A.\\ B.\ 0 C.\" D.0x48.设整型变量a、b的值均为5,则表达式(m=n=a++)/(n=b-2)的值为( B)。
A.0 B.1 C.2 D.39.设a的值为5,执行下列语句后,b的值不为2的是( C)。
A.b=a/2 B.b=6-(--a) C.b=a%2 D.b=(float)a/210.执行语句x=(a=3,b=a--)后,x、a、b的值依次是( C)。
国家开放大学形成性考核01000《可编程控制器应用》形考任务(1-4)试题及答案
国开形成性考核《可编程控制器应用》形考任务(1-4)试题及答案形成性作业1一、单选题(10小题,每小题3分,共30分)题目:1、1.可编程序控制器采用微处理器作为中央处理单元,可以对逻辑量进行控制,也可以对俄)进行控制。
【A】:输入【B】:常量【C】:模拟量【D】:增量题目:2、2. PLC具有逻辑运算功能,能够描述继电器触点的串联和(A)等各种连接。
【A】:并联【B】:逻辑【C】:温度【D】:数字量题目:3、3. PLC具有A/D转换和(C)功能,完成对模拟量的控制与调节。
【A】:S/D转换【B】:A/G转换【C】:D/A转换【D】:D/G转换题目:4、4.按(C)形式分类,PLC可分为整体式和模块式两种。
【A】:逻辑【B】:网络【C】:结构【D】:运算题目:5、5 (B)模块是可编程序控制器系统的运算控制核心。
【A】:CPD【B】:CPU【C】:CDU【D】:CEU题目:6、6 (C)是安装可编程控制器各类模板的机架,可根据实际需要选择。
【A】:结构【B】:网络【C】:导轨【D】:风机题目:7、7 (A)模板用于对PLC内部电路供电。
【A】:电源【B】:光源【C】:导轨【D】:结构题目:8、8(B)是用来将输入端不同电压或电流信号转换成微处理器所能接收的低电平信号。
【A】:电源【B】:输入电压转换【C】:输出电流转换【D】:输出电压转换题目:9、9.输出电平转换是用来将(B)控制的低电平信号转换为控制设备所需的电压或电流信号。
【A】:结构【B】:微处理器【C】:网络【D】:导轨题目:10、10 (D )是在微处理器与I/O回路之间采用的防干扰措施。
【A】:CPD【B】:输出电压转换【C】:CEU【D】:电气隔离二、判断题(正确的打/,错误的打x, 9小题,每小题3分,共27分)题目:11、1. PLC的输入和输出量有开关量和模拟量两种。
开关量I/O用最大I/O点数表示,模拟量I/O点数用最大I/O通道数表示(V)题目:12、2. PLC具有模数转换和数模转换功能,完成对逻辑量的控制与调节(X )题目:13、3. PLC配置有较强的监控功能,能记忆某些异常情况,或当发生异常情况时自动中止运行(V )题目:14、4.传统继电器接触器控制系统的控制功能必须通过修改控制器件和接线来实现(V)题目:15、5.可编程控制系统的控制功能必须通过修改控制器件和接线来实现(X )题目:16、6.输入输出模板必须与CPU模板放置在一起(X)题目:17、7.集散控制系统由单回路仪表控制系统发展起来,主要侧重于回路调节功能(X)题目:18、8. PLC的扫描周期仅取决于程序的长度(X)题目:19、9. PLC的扫描周期仅取决于CPU模板的运算速度(X)三、多选题(7小题,前6小题每题6分,第7小题7分,共43分)题目:20.1.以下传统继电器接触器控制系统和可编程控制系统的特点正确的是(ABCD )。
海大 曲少珍 老师 C程,第六章 数组 题与答案
作业2:数值型数组的基本操作(注:请保存好电子版程序.c)一.一维数值型数组:1.一维数值型数组的输入、输出编程1:若有int a[6]; 请编写程序实现该数组元素的输入和输出。
(分别用两种地址和元素表示形式完成输入输出)2.一维数值型数组的排序:(1)冒泡法(2)选择法(3)比较法编程2:用冒泡法完成排序:做手册7实验一,完成三个冒泡程序的编写。
编程3:若有int a[6]={7,6,5,1,2,3},请编写程序应用选择法将数组元素升序存放。
参见手册7拾漏补遗编程4:若有int a[6]={7,6,5,1,2,3},请编写程序应用选择法将数组元素升序存放。
参见手册7拾漏补遗3.一维数值型数组的查找:(1)线性查找法(2)二分查找法(其前提是数组已经排序)编程5:若有int a[6]={7,2,5,1,2,5},运行程序时用户从键盘键入一个要查找的数据,程序应用线性查找算法查找数组中是否含有该数值.若有,输出其所有匹配元素所在的位置(数组的下标),若没有提示用户。
编程6:若有int a[6]={1,3,5,9,13,16}, 运行程序时用户从键盘键入一个要查找的数据,应用二分查找算法查找数组中是否含有该数值,若有输出其所在的位置(数组的下标),若没有提示用户。
(参见手册7拾漏补遗或者课堂幻灯片)4.一维数值型数组的插入:(1)插入一个数据到用户指定的数组位置:头部/中间/尾部编程7:若有定义int a[7]={7,6,5,1,2,3},用户输入插入位置和插入的数据,程序完成插入操作后重新显示数组所有元素。
编程8:若有定义int a[7]={ 1,7,9,11,14,20},运行程序,用户从键盘键入一个值,程序将该值插入到合适的位置后显示所有数组元素。
(注意数组已排序)(2)连续插入编程9:连续插入若干个用户键入的数据到排序数组中,直至数组满或者输入某个结束标记终止程序。
5.一维数值型数组的删除:删除的处理:将删除位置的数值置为某个约定的标记(如-1)(1)删除用户指定的位置的元素:头部、中间、尾部编程10:若有定义int a[6]={7,6,5,1,2,3},实现一个元素的删除(运行时用户键入要删除的元素位置)(2)删除与用户给定值相匹配的所有数组元素编程11:若有定义int a[7]={6,7,7,5,4,4,4}, 运行程序,用户键入一个值,若数组中含有与之匹配的值则将这些值全部删除。
数据结构(C语言版)第2版习题答案解析-严蔚敏 (2)
数据结构(C语言版)(第2版)课后习题答案李冬梅2015.3目录第1章绪论.............................................................. 第2章线性表............................................................ 第3章栈和队列.......................................................... 第4章串、数组和广义表.................................................. 第5章树和二叉树........................................................ 第6章图 (40)第7章查找.............................................................. 第8章排序..............................................................第1章绪论1.简述下列概念:数据、数据元素、数据项、数据对象、数据结构、逻辑结构、存储结构、抽象数据类型。
答案:数据:是客观事物的符号表示,指所有能输入到计算机中并被计算机程序处理的符号的总称。
如数学计算中用到的整数和实数,文本编辑所用到的字符串,多媒体程序处理的图形、图像、声音、动画等通过特殊编码定义后的数据。
数据元素:是数据的基本单位,在计算机中通常作为一个整体进行考虑和处理。
在有些情况下,数据元素也称为元素、结点、记录等。
数据元素用于完整地描述一个对象,如一个学生记录,树中棋盘的一个格局(状态)、图中的一个顶点等。
数据项:是组成数据元素的、有独立含义的、不可分割的最小单位。
例如,学生基本信息表中的学号、姓名、性别等都是数据项。
《数据结构(C语言版 第2版)》(严蔚敏 著)第七章练习题答案
《数据结构(C语言版第2版)》(严蔚敏著)第七章练习题答案第7章查找1.选择题(1)对n个元素的表做顺序查找时,若查找每个元素的概率相同,则平均查找长度为()。
A.(n-1)/2B.n/2C.(n+1)/2D.n答案:C解释:总查找次数N=1+2+3+…+n=n(n+1)/2,则平均查找长度为N/n=(n+1)/2。
(2)适用于折半查找的表的存储方式及元素排列要求为()。
A.链接方式存储,元素无序B.链接方式存储,元素有序C.顺序方式存储,元素无序D.顺序方式存储,元素有序答案:D解释:折半查找要求线性表必须采用顺序存储结构,而且表中元素按关键字有序排列。
(3)如果要求一个线性表既能较快的查找,又能适应动态变化的要求,最好采用()查找法。
A.顺序查找B.折半查找C.分块查找D.哈希查找答案:C解释:分块查找的优点是:在表中插入和删除数据元素时,只要找到该元素对应的块,就可以在该块内进行插入和删除运算。
由于块内是无序的,故插入和删除比较容易,无需进行大量移动。
如果线性表既要快速查找又经常动态变化,则可采用分块查找。
(4)折半查找有序表(4,6,10,12,20,30,50,70,88,100)。
若查找表中元素58,则它将依次与表中()比较大小,查找结果是失败。
A.20,70,30,50B.30,88,70,50C.20,50D.30,88,50答案:A解释:表中共10个元素,第一次取⎣(1+10)/2⎦=5,与第五个元素20比较,58大于20,再取⎣(6+10)/2⎦=8,与第八个元素70比较,依次类推再与30、50比较,最终查找失败。
(5)对22个记录的有序表作折半查找,当查找失败时,至少需要比较()次关键字。
A.3B.4C.5D.6答案:B解释:22个记录的有序表,其折半查找的判定树深度为⎣log222⎦+1=5,且该判定树不是满二叉树,即查找失败时至多比较5次,至少比较4次。
(6)折半搜索与二叉排序树的时间性能()。
数据结构课后习题答案详解(C语言版_严蔚敏) 2
数据结构习题集答案(C语言版严蔚敏)第2章线性表2.1 描述以下三个概念的区别:头指针,头结点,首元结点(第一个元素结点)。
解:头指针是指向链表中第一个结点的指针。
首元结点是指链表中存储第一个数据元素的结点。
头结点是在首元结点之前附设的一个结点,该结点不存储数据元素,其指针域指向首元结点,其作用主要是为了方便对链表的操作。
它可以对空表、非空表以及首元结点的操作进行统一处理。
2.2 填空题。
解:(1) 在顺序表中插入或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与元素在表中的位置有关。
(2) 顺序表中逻辑上相邻的元素的物理位置必定紧邻。
单链表中逻辑上相邻的元素的物理位置不一定紧邻。
(3) 在单链表中,除了首元结点外,任一结点的存储位置由其前驱结点的链域的值指示。
(4) 在单链表中设置头结点的作用是插入和删除首元结点时不用进行特殊处理。
2.3 在什么情况下用顺序表比链表好?解:当线性表的数据元素在物理位置上是连续存储的时候,用顺序表比用链表好,其特点是可以进行随机存取。
2.4 对以下单链表分别执行下列各程序段,并画出结果示意图。
解:2.5 画出执行下列各行语句后各指针及链表的示意图。
L=(LinkList)malloc(sizeof(LNode)); P=L;for(i=1;i<=4;i++){P->next=(LinkList)malloc(sizeof(LNode));P=P->next; P->data=i*2-1;}P->next=NULL;for(i=4;i>=1;i--) Ins_LinkList(L,i+1,i*2);for(i=1;i<=3;i++) Del_LinkList(L,i);解:2.6 已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。
a. 在P结点后插入S结点的语句序列是__________________。
严蔚敏版数据结构(C语言版)参考答案第六章
第六章树和二叉树6.33int Is_Descendant_C(int u,int v)//在孩子存储结构上判断u是否v的子孙,是则返回1,否则返回0{if(u==v) return 1;else{if(L[v])if (Is_Descendant(u,L[v])) return 1;if(R[v])if (Is_Descendant(u,R[v])) return 1; //这是个递归算法}return 0;}//Is_Descendant_C6.34int Is_Descendant_P(int u,int v)//在双亲存储结构上判断u是否v的子孙,是则返回1,否则返回0{for(p=u;p!=v&&p;p=T[p]);if(p==v) return 1;else return 0;}//Is_Descendant_P6.35这一题根本不需要写什么算法,见书后注释:两个整数的值是相等的.6.36int Bitree_Sim(Bitree B1,Bitree B2)//判断两棵树是否相似的递归算法{if(!B1&&!B2) return 1;elseif(B1&&B2&&Bitree_Sim(B1->lchild,B2->lchild)&&Bitree_Sim(B1->rchild,B2->rc hild))return 1;else return 0;}//Bitree_Sim6.37void PreOrder_Nonrecursive(Bitree T)//先序遍历二叉树的非递归算法{InitStack(S);Push(S,T); //根指针进栈while(!StackEmpty(S)){while(Gettop(S,p)&&p){visit(p->data);push(S,p->lchild);} //向左走到尽头pop(S,p);if(!StackEmpty(S)){pop(S,p);push(S,p->rchild); //向右一步}}//while}//PreOrder_Nonrecursive6.38typedef struct {BTNode* ptr;enum {0,1,2} mark;} PMType; //有mark域的结点指针类型void PostOrder_Stack(BiTree T)//后续遍历二叉树的非递归算法,用栈{PMType a;InitStack(S); //S的元素为PMType类型Push (S,{T,0}); //根结点入栈while(!StackEmpty(S)){Pop(S,a);switch(a.mark){case 0:Push(S,{a.ptr,1}); //修改mark域if(a.ptr->lchild) Push(S,{a.ptr->lchild,0}); //访问左子树break;case 1:Push(S,{a.ptr,2}); //修改mark域if(a.ptr->rchild) Push(S,{a.ptr->rchild,0}); //访问右子树break;case 2:visit(a.ptr); //访问结点,返回}}//while}//PostOrder_Stack分析:为了区分两次过栈的不同处理方式,在堆栈中增加一个mark域,mark=0表示刚刚访问此结点,mark=1表示左子树处理结束返回,mark=2表示右子树处理结束返回.每次根据栈顶元素的mark域值决定做何种动作.6.39typedef struct {int data;EBTNode *lchild;EBTNode *rchild;EBTNode *parent;enum {0,1,2} mark;} EBTNode,EBitree; //有mark域和双亲指针域的二叉树结点类型void PostOrder_Nonrecursive(EBitree T)//后序遍历二叉树的非递归算法,不用栈{p=T;while(p)switch(p->mark){case 0:p->mark=1;if(p->lchild) p=p->lchild; //访问左子树break;case 1:p->mark=2;if(p->rchild) p=p->rchild; //访问右子树break;case 2:visit(p);p->mark=0; //恢复mark值p=p->parent; //返回双亲结点}}//PostOrder_Nonrecursive分析:本题思路与上一题完全相同,只不过结点的mark值是储存在结点中的,而不是暂存在堆栈中,所以访问完毕后要将mark域恢复为0,以备下一次遍历.6.40typedef struct {int data;PBTNode *lchild;PBTNode *rchild;PBTNode *parent;} PBTNode,PBitree; //有双亲指针域的二叉树结点类型void Inorder_Nonrecursive(PBitree T)//不设栈非递归遍历有双亲指针的二叉树{p=T;while(p->lchild) p=p->lchild; //向左走到尽头while(p){visit(p);if(p->rchild) //寻找中序后继:当有右子树时{p=p->rchild;while(p->lchild) p=p->lchild; //后继就是在右子树中向左走到尽头}else if(p->parent->lchild==p) p=p->parent; //当自己是双亲的左孩子时后继就是双亲else{p=p->parent;while(p->parent&&p->parent->rchild==p) p=p->parent;p=p->parent;} //当自己是双亲的右孩子时后继就是向上返回直到遇到自己是在其左子树中的祖先}//while}//Inorder_Nonrecursive6.41int c,k; //这里把k和计数器c作为全局变量处理void Get_PreSeq(Bitree T)//求先序序列为k的结点的值{if(T){c++; //每访问一个子树的根都会使前序序号计数器加1if(c==k){printf("Value is %d\n",T->data);exit (1);}else{Get_PreSeq(T->lchild); //在左子树中查找Get_PreSeq(T->rchild); //在右子树中查找}}//if}//Get_PreSeqmain(){...scanf("%d",&k);c=0; //在主函数中调用前,要给计数器赋初值0Get_PreSeq(T,k);...}//main6.42int LeafCount_BiTree(Bitree T)//求二叉树中叶子结点的数目{if(!T) return 0; //空树没有叶子else if(!T->lchild&&!T->rchild) return 1; //叶子结点else return Leaf_Count(T->lchild)+Leaf_Count(T->rchild);//左子树的叶子数加上右子树的叶子数}//LeafCount_BiTree6.43void Bitree_Revolute(Bitree T)//交换所有结点的左右子树{T->lchild<->T->rchild; //交换左右子树if(T->lchild) Bitree_Revolute(T->lchild);if(T->rchild) Bitree_Revolute(T->rchild); //左右子树再分别交换各自的左右子树}//Bitree_Revolute6.44int Get_Sub_Depth(Bitree T,int x)//求二叉树中以值为x的结点为根的子树深度{if(T->data==x){printf("%d\n",Get_Depth(T)); //找到了值为x的结点,求其深度exit 1;}else{if(T->lchild) Get_Sub_Depth(T->lchild,x);if(T->rchild) Get_Sub_Depth(T->rchild,x); //在左右子树中继续寻找}}//Get_Sub_Depthint Get_Depth(Bitree T)//求子树深度的递归算法{if(!T) return 0;else{m=Get_Depth(T->lchild);n=Get_Depth(T->rchild);return (m>n?m:n)+1;}//Get_Depth6.45void Del_Sub_x(Bitree T,int x)//删除所有以元素x为根的子树{if(T->data==x) Del_Sub(T); //删除该子树else{if(T->lchild) Del_Sub_x(T->lchild,x);if(T->rchild) Del_Sub_x(T->rchild,x); //在左右子树中继续查找}//else}//Del_Sub_xvoid Del_Sub(Bitree T)//删除子树T{if(T->lchild) Del_Sub(T->lchild);if(T->rchild) Del_Sub(T->rchild);free(T);}//Del_Sub6.46void Bitree_Copy_Nonrecursive(Bitree T,Bitree &U)//非递归复制二叉树{InitStack(S1);InitStack(S2);push(S1,T); //根指针进栈U=(BTNode*)malloc(sizeof(BTNode));U->data=T->data;q=U;push(S2,U);while(!StackEmpty(S)){while(Gettop(S1,p)&&p){q->lchild=(BTNode*)malloc(sizeof(BTNode));q=q->lchild;q->data=p->data;push(S1,p->lchild);push(S2,q);} //向左走到尽头pop(S1,p);pop(S2,q);if(!StackEmpty(S1)){pop(S1,p);pop(S2,q);q->rchild=(BTNode*)malloc(sizeof(BTNode));q=q->rchild;q->data=p->data;push(S1,p->rchild); //向右一步push(S2,q);}//while}//BiTree_Copy_Nonrecursive分析:本题的算法系从6.37改写而来.6.47void LayerOrder(Bitree T)//层序遍历二叉树{InitQueue(Q); //建立工作队列EnQueue(Q,T);while(!QueueEmpty(Q)){DeQueue(Q,p);visit(p);if(p->lchild) EnQueue(Q,p->lchild);if(p->rchild) EnQueue(Q,p->rchild);}}//LayerOrder6.48int found=FALSE;Bitree* Find_Near_Ancient(Bitree T,Bitree p,Bitree q)//求二叉树T中结点p和q的最近共同祖先{Bitree pathp[ 100 ],pathq[ 100 ] //设立两个辅助数组暂存从根到p,q的路径Findpath(T,p,pathp,0);found=FALSE;Findpath(T,q,pathq,0); //求从根到p,q的路径放在pathp和pathq中for(i=0;pathp[i]==pathq[i]&&pathp[i];i++); //查找两条路径上最后一个相同结点 return pathp[--i];}//Find_Near_Ancientvoid Findpath(Bitree T,Bitree p,Bitree path[ ],int i)//求从T到p路径的递归算法{if(T==p){found=TRUE;return; //找到}path[i]=T; //当前结点存入路径if(T->lchild) Findpath(T->lchild,p,path,i+1); //在左子树中继续寻找if(T->rchild&&!found) Findpath(T->rchild,p,path,i+1); //在右子树中继续寻找if(!found) path[i]=NULL; //回溯}//Findpathint IsFull_Bitree(Bitree T)//判断二叉树是否完全二叉树,是则返回1,否则返回0 {InitQueue(Q);flag=0;EnQueue(Q,T); //建立工作队列while(!QueueEmpty(Q)){DeQueue(Q,p);if(!p) flag=1;else if(flag) return 0;else{EnQueue(Q,p->lchild);EnQueue(Q,p->rchild); //不管孩子是否为空,都入队列}}//whilereturn 1;}//IsFull_Bitree分析:该问题可以通过层序遍历的方法来解决.与6.47相比,作了一个修改,不管当前结点是否有左右孩子,都入队列.这样当树为完全二叉树时,遍历时得到是一个连续的不包含空指针的序列.反之,则序列中会含有空指针.6.50Status CreateBitree_Triplet(Bitree &T)//输入三元组建立二叉树{if(getchar()!='^') return ERROR;T=(BTNode*)malloc(sizeof(BTNode));p=T;p->data=getchar();getchar(); //滤去多余字符InitQueue(Q);EnQueue(Q,T);while((parent=getchar())!='^'&&(child=getchar())&&(side=getchar())){while(QueueHead(Q)!=parent&&!QueueEmpty(Q)) DeQueue(Q,e);if(QueueEmpty(Q)) return ERROR; //未按层序输入p=QueueHead(Q);q=(BTNode*)malloc(sizeof(BTNode));if(side=='L') p->lchild=q;else if(side=='R') p->rchild=q;else return ERROR; //格式不正确q->data=child;EnQueue(Q,q);}return OK;}//CreateBitree_TripletStatus Print_Expression(Bitree T)//按标准形式输出以二叉树存储的表达式{if(T->data是字母) printf("%c",T->data);else if(T->data是操作符){if(!T->lchild||!T->rchild) return ERROR; //格式错误if(T->lchild->data是操作符&&T->lchild->data优先级低于T->data){printf("(");if(!Print_Expression(T->lchild)) return ERROR;printf(")");} //注意在什么情况下要加括号else if(!Print_Expression(T->lchild)) return ERROR;if(T->rchild->data是操作符&&T->rchild->data优先级低于T->data){printf("(");if(!Print_Expression(T->rchild)) return ERROR;printf(")");}else if(!Print_Expression(T->rchild)) return ERROR;}else return ERROR; //非法字符return OK;}//Print_Expression6.52typedef struct{BTNode node;int layer;} BTNRecord; //包含结点所在层次的记录类型int FanMao(Bitree T)//求一棵二叉树的"繁茂度"{int countd; //count数组存放每一层的结点数InitQueue(Q); //Q的元素为BTNRecord类型EnQueue(Q,{T,0});while(!QueueEmpty(Q)){DeQueue(Q,r);count[yer]++;if(r.node->lchild) EnQueue(Q,{r.node->lchild,yer+1});if(r.node->rchild) EnQueue(Q,{r.node->rchild,yer+1});} //利用层序遍历来统计各层的结点数h=yer; //最后一个队列元素所在层就是树的高度for(maxn=count[0],i=1;count[i];i++)if(count[i]>maxn) maxn=count[i]; //求层最大结点数return h*maxn;}//FanMao分析:如果不允许使用辅助数组,就必须在遍历的同时求出层最大结点数,形式上会复杂一些,你能写出来吗?6.53int maxh;Status Printpath_MaxdepthS1(Bitree T)//求深度等于树高度减一的最靠左的结点{Bitree pathd;maxh=Get_Depth(T); //Get_Depth函数见6.44if(maxh<2) return ERROR; //无符合条件结点Find_h(T,1);return OK;}//Printpath_MaxdepthS1void Find_h(Bitree T,int h)//寻找深度为maxh-1的结点{path[h]=T;if(h==maxh-1){for(i=1;path[i];i++) printf("%c",path[i]->data);exit; //打印输出路径}else{if(T->lchild) Find_h(T->lchild,h+1);if(T->rchild) Find_h(T->rchild,h+1);}path[h]=NULL; //回溯}//Find_h6.54Status CreateBitree_SqList(Bitree &T,SqList sa)//根据顺序存储结构建立二叉链表{Bitree ptr[st+1]; //该数组储存与sa中各结点对应的树指针if(!st){T=NULL; //空树return;}ptr[1]=(BTNode*)malloc(sizeof(BTNode));ptr[1]->data=sa.elem[1]; //建立树根T=ptr[1];for(i=2;i<=st;i++){if(!sa.elem[i]) return ERROR; //顺序错误ptr[i]=(BTNode*)malloc(sizeof(BTNode));ptr[i]->data=sa.elem[i];j=i/2; //找到结点i的双亲jif(i-j*2) ptr[j]->rchild=ptr[i]; //i是j的右孩子else ptr[j]->lchild=ptr[i]; //i是j的左孩子}return OK;}//CreateBitree_SqList6.55int DescNum(Bitree T)//求树结点T的子孙总数填入DescNum域中,并返回该数{if(!T) return -1;else d=(DescNum(T->lchild)+DescNum(T->rchild)+2); //计算公式T->DescNum=d;return d;}//DescNum分析:该算法时间复杂度为O(n),n为树结点总数.注意:为了能用一个统一的公式计算子孙数目,所以当T为空指针时,要返回-1而不是0.6.56BTNode *PreOrder_Next(BTNode *p)//在先序后继线索二叉树中查找结点p的先序后继,并返回指针{if(p->lchild) return p->lchild;else return p->rchild;}//PreOrder_Next分析:总觉得不会这么简单.是不是哪儿理解错了?6.57Bitree PostOrder_Next(Bitree p)//在后序后继线索二叉树中查找结点p的后序后继,并返回指针{if(p->rtag) return p->rchild; //p有后继线索else if(!p->parent) return NULL; //p是根结点else if(p==p->parent->rchild) return p->parent; //p是右孩子else if(p==p->parent->lchild&&p->parent->tag)return p->parent; //p是左孩子且双亲没有右孩子else //p是左孩子且双亲有右孩子{q=p->parent->rchild;while(!q->ltag||!q->rtag){if(!q->ltag) q=q->lchild;else q=q->rchild;} //从p的双亲的右孩子向下走到底return q;}//else}//PostOrder_Next6.58Status Insert_BiThrTree(BiThrTree &T,BiThrTree &p,BiThrTree &x)//在中序线索二叉树T的结点p下插入子树x{if(!p->ltag&&!p->rtag) return INFEASIBLE; //无法插入if(p->ltag) //x作为p的左子树{s=p->lchild; //s为p的前驱p->ltag=Link;p->lchild=x;q=x;while(q->lchild) q=q->lchild;q->lchild=s; //找到子树中的最左结点,并修改其前驱指向sq=x;while(q->rchild) q=q->rchild;q->rchild=p; //找到子树中的最右结点,并修改其前驱指向p}else //x作为p的右子树{s=p->rchild; //s为p的后继p->rtag=Link;p->rchild=x;q=x;while(q->rchild) q=q->rchild;q->rchild=s; //找到子树中的最右结点,并修改其前驱指向sq=x;while(q->lchild) q=q->lchild;q->lchild=p; //找到子树中的最左结点,并修改其前驱指向p}return OK;}//Insert_BiThrTree6.59void Print_CSTree(CSTree T)//输出孩子兄弟链表表示的树T的各边{for(child=T->firstchild;child;child=child->nextsib){printf("(%c,%c),",T->data,child->data);Print_CSTree(child);}}//Print_CSTree6.60int LeafCount_CSTree(CSTree T)//求孩子兄弟链表表示的树T的叶子数目{if(!T->firstchild) return 1; //叶子结点else{count=0;for(child=T->firstchild;child;child=child->nextsib)count+=LeafCount_CSTree(child);return count; //各子树的叶子数之和}}//LeafCount_CSTree6.61int GetDegree_CSTree(CSTree T)//求孩子兄弟链表表示的树T的度{if(!T->firstchild) return 0; //空树else{degree=0;for(p=T->firstchild;p;p=p->nextsib) degree++;//本结点的度for(p=T->firstchild;p;p=p->nextsib){d=GetDegree_CSTree(p);if(d>degree) degree=d; //孩子结点的度的最大值}return degree;}//else}//GetDegree_CSTree6.62int GetDepth_CSTree(CSTree T)//求孩子兄弟链表表示的树T的深度{if(!T) return 0; //空树else{for(maxd=0,p=T->firstchild;p;p=p->nextsib)if((d=GetDepth_CSTree(p))>maxd) maxd=d; //子树的最大深度return maxd+1;}}//GetDepth_CSTree6.63int GetDepth_CTree(CTree A)//求孩子链表表示的树A的深度{return SubDepth(A.r);}//GetDepth_CTreeint SubDepth(int T)//求子树T的深度{if(!A.nodes[T].firstchild) return 1;for(sd=1,p=A.nodes[T].firstchild;p;p=p->next)if((d=SubDepth(p->child))>sd) sd=d;return sd+1;}//SubDepth6.64int GetDepth_PTree(PTree T)//求双亲表表示的树T的深度{maxdep=0;for(i=0;i<T.n;i++){dep=0;for(j=i;j>=0;j=T.nodes[j].parent) dep++; //求每一个结点的深度if(dep>maxdep) maxdep=dep;}return maxdep;}//GetDepth_PTree6.65char Pred,Ind; //假设前序序列和中序序列已经分别储存在数组Pre和In中Bitree Build_Sub(int Pre_Start,int Pre_End,int In_Start,int In_End)//由子树的前序和中序序列建立其二叉链表{sroot=(BTNode*)malloc(sizeof(BTNode)); //建根sroot->data=Pre[Pre_Start];for(i=In_Start;In[i]!=sroot->data;i++); //在中序序列中查找子树根leftlen=i-In_Start;rightlen=In_End-i; //计算左右子树的大小if(leftlen){lroot=Build_Sub(Pre_Start+1,Pre_Start+leftlen,In_Start,In_Start+leftlen-1);sroot->lchild=lroot;} //建左子树,注意参数表的计算if(rightlen){rroot=Build_Sub(Pre_End-rightlen+1,Pre_End,In_End-rightlen+1,In_End);sroot->rchild=rroot;} //建右子树,注意参数表的计算return sroot; //返回子树根}//Build_Submain(){...Build_Sub(1,n,1,n); //初始调用参数,n为树结点总数...}分析:本算法利用了这样一个性质,即一棵子树在前序和中序序列中所占的位置总是连续的.因此,就可以用起始下标和终止下标来确定一棵子树.Pre_Start,Pre_End,In_Start和In_End分别指示子树在前序子序列里的起始下标,终止下标,和在中序子序列里的起始和终止下标.6.66typedef struct{CSNode *ptr;CSNode *lastchild;} NodeMsg; //结点的指针和其最后一个孩子的指针Status Bulid_CSTree_PTree(PTree T)//由树T的双亲表构造其孩子兄弟链表{NodeMsg Treed;for(i=0;i<T.n;i++){Tree[i].ptr=(CSNode*)malloc(sizeof(CSNode));Tree[i].ptr->data=T.node[i].data; //建结点if(T.nodes[i].parent>=0) //不是树根{j=T.nodes[i].parent; //本算法要求双亲表必须是按层序存储if(!(Tree[j].lastchild)) //双亲当前还没有孩子Tree[j].ptr->firstchild=Tree[i].ptr; //成为双亲的第一个孩子else //双亲已经有了孩子Tree[j].lastchild->nextsib=Tree[i].ptr; //成为双亲最后一个孩子的下一个兄弟 Tree[j].lastchild=Tree[i].ptr; //成为双亲的最后一个孩子}//if}//for}//Bulid_CSTree_PTree6.67typedef struct{char data;CSNode *ptr;CSNode *lastchild;} NodeInfo; //结点数据,结点指针和最后一个孩子的指针Status CreateCSTree_Duplet(CSTree &T)//输入二元组建立树的孩子兄弟链表{NodeInfo Treed;n=1;k=0;if(getchar()!='^') return ERROR; //未按格式输入if((c=getchar())=='^') T=NULL; //空树Tree[0].ptr=(CSNode*)malloc(sizeof(CSNode));Tree[0].data=c;Tree[0].ptr->data=c;while((p=getchar())!='^'&&(c=getchar())!='^'){Tree[n].ptr=(CSNode*)malloc(sizeof(CSNode));Tree[n].data=c;Tree[n].ptr->data=c;for(k=0;Tree[k].data!=p;k++); //查找当前边的双亲结点if(Tree[k].data!=p) return ERROR; //未找到:未按层序输入r=Tree[k].ptr;if(!r->firstchild)r->firstchild=Tree[n].ptr;else Tree[k].lastchild->nextsib=Tree[n].ptr;Tree[k].lastchild=Tree[n].ptr; //这一段含义同上一题n++;}//whilereturn OK;}//CreateCSTree_Duplet6.68Status CreateCSTree_Degree(char node[ ],int degree[ ])//由结点的层序序列和各结点的度构造树的孩子兄弟链表{CSNode * ptrd; //树结点指针的辅助存储ptr[0]=(CSNode*)malloc(sizeof(CSNode));i=0;k=1; //i为当前结点序号,k为当前孩子的序号while(node[i]){ptr[i]->data=node[i];d=degree[i];if(d){ptr[k++]=(CSNode*)malloc(sizeof(CSNode)); //k为当前孩子的序号ptr[i]->firstchild=ptr[k]; //建立i与第一个孩子k之间的联系for(j=2;j<=d;j++){ptr[k++]=(CSNode*)malloc(sizeof(CSNode));ptr[k-1]->nextsib=ptr[k]; //当结点的度大于1时,为其孩子建立兄弟链表}//for}//ifi++;}//while}//CreateCSTree_Degree6.69void Print_BiTree(BiTree T,int i)//按树状打印输出二叉树的元素,i表示结点所在层次,初次调用时i=0{if(T->rchild) Print_BiTree(T->rchild,i+1);for(j=1;j<=i;j++) printf(" "); //打印i个空格以表示出层次printf("%c\n",T->data); //打印T元素,换行if(T->lchild) Print_BiTree(T->rchild,i+1);}//Print_BiTree分析:该递归算法实际上是带层次信息的中序遍历,只不过按照题目要求,顺序为先右后左.6.70Status CreateBiTree_GList(BiTree &T)//由广义表形式的输入建立二叉链表{c=getchar();if(c=='#') T=NULL; //空子树else{T=(CSNode*)malloc(sizeof(CSNode));T->data=c;if(getchar()!='(') return ERROR;if(!CreateBiTree_GList(pl)) return ERROR;T->lchild=pl;if(getchar()!=',') return ERROR;if(!CreateBiTree_GList(pr)) return ERROR;T->rchild=pr;if(getchar()!=')') return ERROR; //这些语句是为了保证输入符合A(B,C)的格式 }return OK;}//CreateBiTree_GList6.71void Print_CSTree(CSTree T,int i)//按凹入表形式打印输出树的元素,i表示结点所在层次,初次调用时i=0{for(j=1;j<=i;j++) printf(" "); //留出i个空格以表现出层次printf("%c\n",T->data); //打印元素,换行for(p=T->firstchild;p;p=p->nextsib)Print_CSTree(p,i+1); //打印子树}//Print_CSTree6.72void Print_CTree(int e,int i)//按凹入表形式打印输出树的元素,i表示结点所在层次{for(j=1;j<=i;j++) printf(" "); //留出i个空格以表现出层次printf("%c\n",T.nodes[e].data); //打印元素,换行for(p=T.nodes[e].firstchild;p;p=p->next)Print_CSTree(p->child,i+1); //打印子树}//Print_CSTreemain(){...Print_CTree(T.r,0); //初次调用时i=0...}//main6.73char c; //全局变量,指示当前字符Status CreateCSTree_GList(CSTree &T)//由广义表形式的输入建立孩子兄弟链表{c=getchar();T=(CSNode*)malloc(sizeof(CSNode));T->data=c;if((c=getchar())=='(') //非叶结点{if(!CreateCSTree_GList(fc)) return ERROR; //建第一个孩子T->firstchild=fc;for(p=fc;c==',';p->nextsib=nc,p=nc) //建兄弟链if(!CreateCSTree_GList(nc)) return ERROR;p->nextsib=NULL;if((c=getchar())!=')') return ERROR; //括号不配对}else T->firtchild=NULL; //叶子结点return OK;}//CreateBiTree_GList分析:书后给出了两个间接递归的算法,事实上合成一个算法在形式上可能更好一些.本算法另一个改进之处在于加入了广义表格式是否合法的判断.6.74{printf("%c",T->data);if(T->firstchild) //非叶结点{printf("(");for(p=T->firstchild;p;p=p->nextsib){PrintGlist_CSTree(p);if(p->nextsib) printf(","); //最后一个孩子后面不需要加逗号}printf(")");}//if}//PrintGlist_CSTree6.75char c;int pos=0; //pos是全局变量,指示已经分配到了哪个结点Status CreateCTree_GList(CTree &T,int &i)//由广义表形式的输入建立孩子链表{c=getchar();T.nodes[pos].data=c;i=pos++; //i是局部变量,指示当前正在处理的子树根if((c=getchar())=='(') //非叶结点{CreateCTree_GList();p=(CTBox*)malloc(sizeof(CTBox));T.nodes[i].firstchild=p;p->child=pos; //建立孩子链的头for(;c==',';p=p->next) //建立孩子链{CreateCTree_GList(T,j); //用j返回分配得到的子树根位置p->child=j;p->next=(CTBox*)malloc(sizeof(CTBox));}p->next=NULL;if((c=getchar())!=')') return ERROR; //括号不配对}//ifelse T.nodes[i].firtchild=NULL; //叶子结点return OK;}//CreateBiTree_GList分析:该算法中,pos变量起着"分配"结点在表中的位置的作用,是按先序序列从上向下分配,因此树根T.r一定等于0,而最终的pos值就是结点数T.n.6.76{printf("%c",T.nodes[i].data);if(T.nodes[i].firstchild) //非叶结点{printf("(");for(p=T->firstchild;p;p=p->nextsib){PrintGlist_CSTree(T,p->child);if(p->nextsib) printf(","); //最后一个孩子后面不需要加逗号 }printf(")");}//if}//PrintGlist_CTree。
严蔚敏数据结构c语言版习题集全答案
说明: 1. 本文是对严蔚敏?数据构造(c语言版)习题集?一书中所有算法设计题目的解决方案,主要作者为kaoyan.计算机版版主一具.以下网友:siice,龙抬头,iamkent,zames,birdthinking等为答案的修订和完善工作提出了珍贵意见,在此表示感;2. 本解答中的所有算法均采用类c语言描述,设计原那么为面向交流、面向阅读,作者不保证程序能够上机正常运行(这种保证实际上也没有任何意义);3. 本解答原那么上只给出源代码以及必要的注释,对于一些难度较高或思路特殊的题目将给出简要的分析说明,对于作者无法解决的题目将给出必要的讨论.目前尚未解决的题目有: 5.20, 10.40;4. 请读者在自己已经解决了某个题目或进展了充分的思考之后,再参考本解答,以保证复习效果;5. 由于作者水平所限,本解答中一定存在不少这样或者那样的错误和缺乏,希望读者们在阅读中多动脑、勤思考,争取发现和纠正这些错误,写出更好的算法来.请将你发现的错误或其它值得改良之处向作者报告: 第一章绪论1.16void print_descending(int x,int y,int z)//按从大到小顺序输出三个数{scanf("%d,%d,%d",&x,&y,&z);if(x<y) x<->y; //<->为表示交换的双目运算符,以下同if(y<z) y<->z;if(x<y) x<->y; //冒泡排序printf("%d %d %d",x,y,z);}//print_descending1.17Status fib(int k,int m,int &f)//求k阶斐波那契序列的第m项的值f{int tempd;if(k<2||m<0) return ERROR;if(m<k-1) f=0;else if (m==k-1) f=1;else{for(i=0;i<=k-2;i++) temp[i]=0;temp[k-1]=1; //初始化for(i=k;i<=m;i++) //求出序列第k至第m个元素的值{sum=0;for(j=i-k;j<i;j++) sum+=temp[j];temp[i]=sum;}f=temp[m];}return OK;}//fib分析:通过保存已经计算出来的结果,此方法的时间复杂度仅为O(m^2).如果采用递归编程(大多数人都会首先想到递归方法),那么时间复杂度将高达O(k^m).1.18typedef struct{char *sport;enum{male,female} gender;char schoolname; //校名为'A','B','C','D'或'E'char *result;int score;} resulttype;typedef struct{int malescore;int femalescore;int totalscore;} scoretype;void summary(resulttype result[ ])//求各校的男女总分和团体总分,假设结果已经储存在result[ ]数组中{scoretype score;i=0;while(result[i].sport!=NULL){switch(result[i].schoolname){case 'A':score[ 0 ].totalscore+=result[i].score; if(result[i].gender==0) score[ 0 ].malescore+=result[i].score; else score[ 0 ].femalescore+=result[i].score;break;case 'B':score.totalscore+=result[i].score;if(result[i].gender==0) score.malescore+=result[i].score;else score.femalescore+=result[i].score;break;……………… }i++;}for(i=0;i<5;i++){printf("School %d:\n",i);printf("Total score of male:%d\n",score[i].malescore);printf("Total score of female:%d\n",score[i].femalescore);printf("Total score of all:%d\n\n",score[i].totalscore);}}//summary1.19Status algo119(int a[ARRSIZE])//求i!*2^i序列的值且不超过maxint{last=1;for(i=1;i<=ARRSIZE;i++){a[i-1]=last*2*i;if((a[i-1]/last)!=(2*i)) reurn OVERFLOW;last=a[i-1];return OK;}}//algo119分析:当某一项的结果超过了maxint时,它除以前面一项的商会发生异常.1.20void polyvalue(){float ad;float *p=a;printf("Input number of terms:");scanf("%d",&n);printf("Input the %d coefficients from a0 to a%d:\n",n,n);for(i=0;i<=n;i++) scanf("%f",p++);printf("Input value of x:");scanf("%f",&x);p=a;xp=1;sum=0; //xp用于存放x的i次方for(i=0;i<=n;i++){sum+=xp*(*p++);xp*=x;}printf("Value is:%f",sum);}//polyvalue第二章线性表2.10Status DeleteK(SqList &a,int i,int k)//删除线性表a中第i个元素起的k个元素{if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;for(count=1;i+count-1<=a.length-k;count++) //注意循环完毕的条件a.elem[i+count-1]=a.elem[i+count+k-1];a.length-=k;return OK;}//DeleteK2.11Status Insert_SqList(SqList &va,int x)//把x插入递增有序表va中{if(va.length+1>va.listsize) return ERROR;va.length++;for(i=va.length-1;va.elem[i]>x&&i>=0;i--)va.elem[i+1]=va.elem[i];va.elem[i+1]=x;return OK;}//Insert_SqList2.12int Listp(SqList A,SqList B)//比拟字符表A和B,并用返回值表示结果,值为正,表示A>B;值为负,表示A<B;值为零,表示A=B {for(i=1;A.elem[i]||B.elem[i];i++)if(A.elem[i]!=B.elem[i]) return A.elem[i]-B.elem[i];return 0;}//Listp2.13LNode* Locate(LinkList L,int x)//链表上的元素查找,返回指针{for(p=l->next;p&&p->data!=x;p=p->next);return p;}//Locate2.14int Length(LinkList L)//求链表的长度{for(k=0,p=L;p->next;p=p->next,k++);return k;}//Length2.15void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把链表hb接在ha后面形成链表hc{while(p->next) p=p->next;p->next=hb;}//ListConcat2.16见书后答案.2.17Status Insert(LinkList &L,int i,int b)//在无头结点链表L的第i个元素之前插入元素b{p=L;q=(LinkList*)malloc(sizeof(LNode));q.data=b;if(i==1){q.next=p;L=q; //插入在链表头部}else{while(--i>1) p=p->next;q->next=p->next;p->next=q; //插入在第i个元素的位置}}//Insert2.18Status Delete(LinkList &L,int i)//在无头结点链表L中删除第i个元素{if(i==1) L=L->next; //删除第一个元素else{p=L;while(--i>1) p=p->next;p->next=p->next->next; //删除第i个元素}}//Delete2.19Status Delete_Between(Linklist &L,int mink,int maxk)//删除元素递增排列的链表L中值大于mink且小于maxk的所有元素{p=L;while(p->next->data<=mink) p=p->next; //p是最后一个不大于mink的元素if(p->next) //如果还有比mink更大的元素{q=p->next;while(q->data<maxk) q=q->next; //q是第一个不小于maxk的元素p->next=q;}}//Delete_Between2.20Status Delete_Equal(Linklist &L)//删除元素递增排列的链表L中所有值一样的元素{p=L->next;q=p->next; //p,q指向相邻两元素while(p->next){p=p->next;q=p->next; //当相邻两元素不相等时,p,q都向后推一步}else{while(q->data==p->data){free(q);q=q->next;}p->next=q;p=q;q=p->next; //当相邻元素相等时删除多余元素}//else}//while}//Delete_Equal2.21void reverse(SqList &A)//顺序表的就地逆置{for(i=1,j=A.length;i<j;i++,j--)A.elem[i]<->A.elem[j];}//reverse2.22void LinkList_reverse(Linklist &L)//链表的就地逆置;为简化算法,假设表长大于2{p=L->next;q=p->next;s=q->next;p->next=NULL;while(s->next){q->next=p;p=q;q=s;s=s->next; //把L的元素逐个插入新表表头}q->next=p;s->next=q;L->next=s;}//LinkList_reverse分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.2.23void merge1(LinkList &A,LinkList &B,LinkList &C)//把链表A和B合并为C,A和B的元素间隔排列,且使用原存储空间{p=A->next;q=B->next;C=A;while(p&&q){s=p->next;p->next=q; //将B的元素插入if(s){t=q->next;q->next=s; //如A非空,将A的元素插入}p=s;q=t;}//while}//merge12.24void reverse_merge(LinkList &A,LinkList &B,LinkList &C)//把元素递增排列的链表A和B合并为C,且C中元素递减排列,使用原空间{pa=A->next;pb=B->next;pre=NULL; //pa和pb分别指向A,B的当前元素while(pa||pb){pc=pa;q=pa->next;pa->next=pre;pa=q; //将A的元素插入新表}else{pc=pb;q=pb->next;pb->next=pre;pb=q; //将B的元素插入新表}pre=pc;}C=A;A->next=pc; //构造新表头}//reverse_merge分析:本算法的思想是,按从小到大的顺序依次把A和B的元素插入新表的头部pc处,最后处理A或B的剩余元素.2.25void SqList_Intersect(SqList A,SqList B,SqList &C)//求元素递增排列的线性表A和B的元素的交集并存入C中{i=1;j=1;k=0;while(A.elem[i]&&B.elem[j]){if(A.elem[i]<B.elem[j]) i++;if(A.elem[i]>B.elem[j]) j++;if(A.elem[i]==B.elem[j]){C.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素,i++;j++; //就添加到C中}}//while}//SqList_Intersect2.26void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在链表构造上重做上题{p=A->next;q=B->next;pc=(LNode*)malloc(sizeof(LNode));while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else{s=(LNode*)malloc(sizeof(LNode));s->data=p->data;pc->next=s;pc=s;p=p->next;q=q->next;}}//whileC=pc;}//LinkList_Intersect2.27void SqList_Intersect_True(SqList &A,SqList B)//求元素递增排列的线性表A和B的元素的交集并存回A中{i=1;j=1;k=0;while(A.elem[i]&&B.elem[j]){if(A.elem[i]<B.elem[j]) i++;else if(A.elem[i]>B.elem[j]) j++;A.elem[++k]=A.elem[i]; //当发现了一个在A,B中都存在的元素i++;j++; //且C中没有,就添加到C中}}//whilewhile(A.elem[k]) A.elem[k++]=0;}//SqList_Intersect_True2.28void LinkList_Intersect_True(LinkList &A,LinkList B)//在链表构造上重做上题{p=A->next;q=B->next;pc=A;while(p&&q){if(p->data<q->data) p=p->next;else if(p->data>q->data) q=q->next;else if(p->data!=pc->data){pc=pc->next;pc->data=p->data;p=p->next;q=q->next;}}//while}//LinkList_Intersect_True2.29void SqList_Intersect_Delete(SqList &A,SqList B,SqList C){i=0;j=0;k=0;m=0; //i指示A中元素原来的位置,m为移动后的位置while(i<A.length&&j<B.length&& k<C.length){if(B.elem[j]<C.elem[k]) j++;else if(B.elem[j]>C.elem[k]) k++;else{same=B.elem[j]; //找到了一样元素samewhile(B.elem[j]==same) j++;while(C.elem[k]==same) k++; //j,k后移到新的元素while(i<A.length&&A.elem[i]<same)A.elem[m++]=A.elem[i++]; //需保存的元素移动到新位置while(i<A.length&&A.elem[i]==same) i++; //跳过一样的元素}}//whilewhile(i<A.length)A.elem[m++]=A.elem[i++];//A的剩余元素重新存储。
数据结构C语言版第2版习题答案解析-严蔚敏
数据结构C语言版第2版习题答案解析-严蔚敏在学习计算机科学的道路上,数据结构无疑是一座重要的基石。
而严蔚敏老师的《数据结构(C 语言版)第 2 版》更是众多学子的经典教材。
其中的习题,不仅有助于我们巩固所学知识,还能引导我们深入思考,提高解决实际问题的能力。
接下来,让我们一同走进这些习题的答案解析。
首先,我们来谈谈线性表这一章节的习题。
线性表是数据结构中最基础、最常用的结构之一。
比如有这样一道题:“设计一个算法,从顺序表中删除具有最小值的元素(假设唯一)并由函数返回被删元素的值。
”对于这道题,我们首先需要遍历整个顺序表,找到最小值及其位置。
然后,将其后的元素依次向前移动一位,实现删除操作。
在 C 语言中,可以这样实现:```cinclude <stdioh>int deleteMinElement(int arr, int n) {int min = arr0;int minIndex = 0;for (int i = 1; i < n; i++){if (arri < min) {min = arri;minIndex = i;}}int temp = arrminIndex;for (int i = minIndex; i < n 1; i++){arri = arri + 1;}return temp;}int main(){int arr ={5, 3, 8, 2, 7};int n = sizeof(arr) / sizeof(arr0);int deletedElement = deleteMinElement(arr, n);printf("删除的元素为:%d\n", deletedElement);for (int i = 0; i < n 1; i++){printf("%d ", arri);}return 0;}```再来看栈和队列这部分的习题。
比如:“利用两个栈 S1 和 S2 模拟一个队列,如何实现队列的入队和出队操作?”这就需要我们巧妙地利用栈的特性。
押题宝典国家电网招聘之电网计算机自我提分评估(附答案)
押题宝典国家电网招聘之电网计算机自我提分评估(附答案)单选题(共40题)1、下面关于集线器的缺点描述的是()。
A.集线器不能延伸网络可操作的距离B.集线器不能过滤网络流量C.集线器不能在网络上发送变弱的信号D.集线器不能放大变弱的信号【答案】 B2、下列情况中,可导致失耐受的是:()A.回避TH细胞的耐受B.交叉免疫反应C.TS细胞和TH细胞功能失衡D.隐蔽抗原释放E.以上情况都不是【答案】 A3、已知寄存器R中内容为11100010,经()后变为11110001。
A.算术右移B.逻辑右移C.循环右移D.以上都不是【答案】 A4、某总线有104根信号线,其中数据总线(DB)32根,若总线工作频率为33MHz,则其理论最大传输率是()。
A.33MB/sB.64MB/sC.132MB/sD.164MB/s【答案】 C5、冯·诺依曼计算机中指令和数据均以二进制形式存放在存储器中,CPU 区分它们的依据是()。
A.指令操作码的译码结果B.数补码C.指令周期的不同阶段D.指令和数据所在的存储单元【答案】 C6、以下()不是产生死锁的原因。
A.资源共享B.并发执行的进程数太多C.系统资源不足D.进程推进顺序非法【答案】 B7、采用基址寻址可以扩大寻址范围,且()。
A.基址寄存器的内容由用户确定,在程序执行过程中不能改变B.基址寄存器的内容由操作系统确定,在程序执行过程中不能改变C.基址寄存器的内容由用户确定,在程序执行过程中可以改变D.基址寄存器的内容由操作系统确定,在程序执行过程中可以改变【答案】 B8、网络攻击可分为主动攻击和被动攻击。
主动攻击包括假冒、重放、修改信息和拒绝服务;被动攻击包括网络窃听、截取数据包和流量分析。
以下人为的恶意攻击行为中,属于主动攻击的是()。
A.身份假冒B.数据窃听C.数据流分析D.非法访问【答案】 A9、关于计算机设备间的信息交换,不正确的是()。
A.内存可以直接和CPU进行信息交换B.内存可以直接和硬盘进行信息交换C.硬盘可以直接和CPU进行信息交换D.打印机可以直接和内存进行信息交换【答案】 C10、下列选项中,既属于输入设备又属于输出设备的是()。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、单项选择题
1. 在“机构间私募产品报价与服务系统”的名义持有模式下,代理交易方与合格投资者之间具有()关系,代理交
易方与产品管理人(发行人)之间形成()关系。
A. 直接投资,民事信托
B. 直接投资,直接投资
C. 民事信托,直接投资
D. 民事信托,民事信托
您的答案:D
题目分数:10
此题得分:0.0
2. 在“机构间私募产品报价与服务系统”中,采用直接持有模式时,合格投资者与代理交易方形成()关系;采用
名义持有模式时,合格投资者与代理交易方形成()关系。
A. 直接投资,民事信托
B. 直接投资,直接投资
C. 民事信托,直接投资
D. 民事信托,民事信托
您的答案:A
题目分数:10
此题得分:10.0
二、多项选择题
3. 在“机构间私募产品报价与服务系统”中,参与人可以申请开立的一级产品账户包括()。
A. 受托产品账户
B. 自营产品账户
C. 名义持有产品账户
D. 合格投资者产品账户
您的答案:C,D,B
题目分数:10
此题得分:0.0
4. 在“机构间私募产品报价与服务系统”中,仅具有创设类权限的参与人可以开立的资金结算账户有()。
A. 受托资金结算账户
B. 自营资金结算账户
C. 代理资金结算账户
D. 专用资金结算账户
您的答案:B,A
题目分数:10
此题得分:0.0
5. “机构间私募产品报价与服务系统”登记结算服务具有以下()几方面特征。
A. 种类齐全
B. 方式多样
C. 便捷高效
D. 成本低廉
您的答案:A,B,C,D
题目分数:10
此题得分:10.0
6. “机构间私募产品报价与服务系统”参与人根据业务的需要可以开立的资金结算账户包括()。
A. 受托资金结算账户
B. 自营资金结算账户
C. 代理资金结算账户
D. 专用资金结算账户
您的答案:C,A,B,D
题目分数:10
此题得分:10.0
三、判断题
7. 在“机构间私募产品报价与服务系统”中,资金结算编号要与同类的产品账户和资金结算账户进行绑定。
()
您的答案:正确
题目分数:10
此题得分:10.0
8. “机构间私募产品报价与服务系统”的直接持有模式是针对私募产品管理人(发行人)与代理交易方为同一证券公
司的情况而设定的。
()
您的答案:正确
题目分数:10
此题得分:10.0
9. “机构间私募产品报价与服务系统”仅支持逐笔全额的清算方式。
()
您的答案:错误
题目分数:10
此题得分:10.0
10. 混合持有模式是“机构间私募产品报价与服务系统”主推的持有模式。
()
您的答案:正确
题目分数:10
此题得分:10.0
试卷总得分:70.0
一、单项选择题
1. 在“机构间私募产品报价与服务系统”中,()用于记载参与人在报价系统发行私募产品募集的资金以及用于分
红、付息、兑付的资金。
A. 受托资金结算账户
B. 自营资金结算账户
C. 代理资金结算账户
D. 专用资金结算账户
您的答案:D
题目分数:10
2. 在“机构间私募产品报价与服务系统”中,用于记载参与人管理的基金、资产管理计划等持有的私募产品的账户是
()。
A. 受托产品账户
B. 自营产品账户
C. 名义持有产品账户
D. 合格投资者产品账户
您的答案:A
题目分数:10
此题得分:10.0
二、多项选择题
3. “机构间私募产品报价与服务系统”登记结算服务具有以下()几方面特征。
A. 种类齐全
B. 方式多样
C. 便捷高效
D. 成本低廉
您的答案:D,A,B,C
题目分数:10
此题得分:10.0
4. 在“机构间私募产品报价与服务系统”中,仅具有投资类权限的参与人可以开立的资金结算账户有()。
A. 受托资金结算账户
B. 自营资金结算账户
C. 代理资金结算账户
D. 专用资金结算账户
您的答案:A,B
题目分数:10
此题得分:10.0
5. 以下关于“机构间私募产品报价与服务系统”名义持有模式的说法中,正确的有()。
A. 推行名义持有模式是机构间市场开展业务的需要
B. 推行名义持有模式是私募市场互联互通的需要
C. 推行名义持有模式是券商保护客户资源的需要
D. 推行名义持有模式有助于做实券商托管职能
E. 推行名义持有模式有助于满足客户个性化需求
您的答案:A,C,D,B,E
题目分数:10
此题得分:10.0
6. “机构间私募产品报价与服务系统”参与人根据业务的需要可以开立的资金结算账户包括()。
A. 受托资金结算账户
B. 自营资金结算账户
C. 代理资金结算账户
D. 专用资金结算账户
您的答案:B,D,A,C
题目分数:10
三、判断题
7. 在“机构间私募产品报价与服务系统”中,资金结算编号要与同类的产品账户和资金结算账户进行绑定。
()
您的答案:正确
题目分数:10
此题得分:10.0
8. “机构间私募产品报价与服务系统”的直接持有模式是针对私募产品管理人(发行人)与代理交易方为同一证券公
司的情况而设定的。
()
您的答案:正确
题目分数:10
此题得分:10.0
9. “机构间私募产品报价与服务系统”仅支持逐笔全额的清算方式。
()
您的答案:错误
题目分数:10
此题得分:10.0
10. 混合持有模式是“机构间私募产品报价与服务系统”主推的持有模式。
()
您的答案:正确
题目分数:10
此题得分:10.0
试卷总得分:100.0。