您好,欢迎访问三七文档
第一章3.(1)A(2)C(3)D5.计算下列程序中x=x+1的语句频度for(i=1;i=n;i++)for(j=1;j=i;j++)for(k=1;k=j;k++)x=x+1;【解答】x=x+1的语句频度为:T(n)=1+(1+2)+(1+2+3)+……+(1+2+……+n)=n(n+1)(n+2)/66.编写算法,求一元多项式pn(x)=a0+a1x+a2x2+…….+anxn的值pn(x0),并确定算法中每一语句的执行次数和整个算法的时间复杂度,要求时间复杂度尽可能小,规定算法中不能使用求幂函数。注意:本题中的输入为ai(i=0,1,…n)、x和n,输出为Pn(x0)。算法的输入和输出采用下列方法(1)通过参数表中的参数显式传递(2)通过全局变量隐式传递。讨论两种方法的优缺点,并在算法中以你认为较好的一种实现输入输出。【解答】(1)通过参数表中的参数显式传递优点:当没有调用函数时,不占用内存,调用结束后形参被释放,实参维持,函数通用性强,移置性强。缺点:形参须与实参对应,且返回值数量有限。(2)通过全局变量隐式传递优点:减少实参与形参的个数,从而减少内存空间以及传递数据时的时间消耗缺点:函数通用性降低,移植性差算法如下:通过全局变量隐式传递参数PolyValue(){inti,n;floatx,a[],p;printf(“\nn=”);scanf(“%f”,&n);printf(“\nx=”);scanf(“%f”,&x);for(i=0;in;i++)scanf(“%f”,&a[i]);/*执行次数:n次*/p=a[0];for(i=1;i=n;i++){p=p+a[i]*x;/*执行次数:n次*/x=x*x;}printf(“%f”,p);}算法的时间复杂度:T(n)=O(n)通过参数表中的参数显式传递floatPolyValue(floata[],floatx,intn){floatp,s;inti;p=x;s=a[0];for(i=1;i=n;i++){s=s+a[i]*p;/*执行次数:n次*/p=p*x;}return(p);}算法的时间复杂度:T(n)=O(n)第二章1.填空:(1)在顺序表中插入或删除一个元素,需要平均移动一半元素,具体移动的元素个数与插入或删除的位置有关。(2)线性表有顺序和链式两种存储结构。在顺序表中,线性表的长度在数组定义时就已经确定,是静态保存,在链式表中,整个链表由“头指针”来表示,单链表的长度是动态保存。(3)在顺序表中,逻辑上相邻的元素,其物理位置_一定_____相邻。在单链表中,逻辑上相邻的元素,其物理位置不一定相邻。(4)在带头结点的非空单链表中,头结点的存储位置由头指针指示,首元素结点的存储位置由头结点指示,除首元素结点外,其它任一元素结点的存储位置由其直接前趋的next域指示。2.选择题(1)A(2)已知L是无表头结点的单链表,且P结点既不是首元素结点,也不是尾元素结点。按要求从下列语句中选择合适的语句序列。a.在P结点后插入S结点的语句序列是:D、A。b.在P结点前插入S结点的语句序列是:G、K、H、D、A。c.在表首插入S结点的语句序列是:E、L。d.在表尾插入S结点的语句序列是:(K)、I、A、F。供选择的语句有:AP-next=S;BP-next=P-next-next;CP-next=S-next;DS-next=P-next;ES-next=L;FS-next=NULL;GQ=P;Hwhile(P-next!=Q)P=P-next;Iwhile(P-next!=NULL)P=P-next;JP=Q;KP=L;LL=S;ML=P;(3)D(4)D(5)D4.已知顺序表L递增有序,编写一个算法,将X插入到线性表的适当位置上,以保持线性表的有序性。voidinserX(Seqlist*L,Elemtypex){inti;i=L-length-1;while(i=0&&xL-elem[i]){L-elem[i+1]=L-elem[i];i--;}L-length++;}7试分别以不同的存储结构实现线性表的就地逆值的算法,即在原表的存储空间中将线性表(a1,a2,…,an)逆置为(an,an-1,…,a1)。(1)以顺序表作存储结构,设线性表存于a[1:arrsize]的前elenum个分量中。voidreverseqlist(Seqlist*L){inti;inttemp;for(i=0;iL-length/2;i++){temp=L-elem[i];L-elem[i]=L-elem[L-length-i-1];L-elem[L-length-i-1]=temp;}}(2)以单链表作存储结构。voidreverselinklist(linklist*head){Linklist*p,*q;p=head-next;head-next=NULL;while(p-next!=NULL){q=p-next;p-next=head-next;head-next=p;p=q;}}11将线性表A=(a1,a2,……am),B=(b1,b2,……bn)合并成线性表C,C=(a1,b1,……am,bm,bm+1,…….bn)m=n,或C=(a1,b1,……an,bn,an+1,……am)mn,线性表A、B、C以单链表作为存储结构,且C表利用A表和B表中的结点空间构成。注意:单链表的长度值m和n均未显式存储。【解答】算法如下:LinkListmerge(LinkListA,LinkListB,LinkListC){Node*pa,*qa,*pb,*qb,*p;pa=A-next;/*pa表示A的当前结点*/pb=B-next;p=A;/*利用p来指向新连接的表的表尾,初始值指向表A的头结点*/while(pa!=NULL&&pb!=NULL)/*利用尾插法建立连接之后的链表*/{qa=pa-next;qb=qb-next;p-next=pa;/*交替选择表A和表B中的结点连接到新链表中;*/p=pa;p-next=pb;p=pb;pa=qa;pb=qb;}if(pa!=NULL)p-next=pa;/*A的长度大于B的长度*/if(pb!=NULL)p-next=pb;/*B的长度大于A的长度*/C=A;Return(C);}第三章1B2C3C8假设表达式由单字母变量和双目四则运算构成。试写一个算法,将一个通常书写形式且书写正确的表达式转为逆波兰式。【分析】算法的思想:所有的变量在逆波兰式中出现的先后顺序和在原表达式中出现的相同,因此只需要设立一个栈,根据操作符的优先级调整它们在逆波兰式中出现的顺序。#includestdio.h#includemalloc.h#defineSTACK_INIT_SIZE100#defineSTACK_INCREAMENT10typedefstruct{//栈char*base;char*top;intstackSize;}Stack;voidinitStack(Stack&stack){//初始化栈stack.base=stack.top=(char*)malloc(sizeof(char)*STACK_INIT_SIZE);stack.stackSize=STACK_INIT_SIZE;}voidpush(Stack&S,charp){//入栈if(S.top-S.base=S.stackSize){S.base=(char*)realloc(S.base,(S.stackSize+STACK_INCREAMENT)*sizeof(char));S.top=S.stackSize+S.base;S.stackSize+=STACK_INCREAMENT;}*S.top++=p;}voidpop(Stack&stack,char&p){//出栈if(stack.base==stack.top){p=NULL;return;}p=*--stack.top;}chargetTop(Stackstack){//获得栈顶元素if(stack.base==stack.top)returnNULL;return*(stack.top-1);}boolisAlpha(charp){//判断是不是字母return(p='a'&&p='z')||(p='A'&&p='Z')?true:false;}intprecede(chara,charb){switch(a){case'/':case'*':return1;break;case'+':case'-':switch(b){case'/':case'*':return-1;break;default:return1;}break;default:switch(b){case'#':return0;break;default:return-1;}}}voidNiBoLan(char*str,char*newStr){//转换成逆波兰式Stackstack;initStack(stack);char*p,*q,c;p=str;q=newStr;push(stack,'#');while(*p){if(isAlpha(*p))*q++=*p;else{c=getTop(stack);if(precede(*p,c)0)push(stack,*p);else{while(precede(getTop(stack),*p)=0&&*p){pop(stack,c);*q++=c;}push(stack,*p);}}p++;}}voidmain(){charstr[100];charnewStr[100];inti;for(i=0;i100;i++)str[i]=newStr[i]='\0';printf(请输入表达式:\n);scanf(%s,str);NiBoLan(str,newStr);printf(其对应的逆波兰式为:%s\n,newStr);}10要求循环队列不损失一个空间全部都能得到利用,设置一个标志tag,以tag为0或1来区分头尾指针相同时的队列状态的空与满,请编写与此相应的入队与出队算法。入队算法:intEnterQueue(SeqQueue*Q,QueueElementTypex){/*将元素x入队*/if(Q-front==Q-front&&tag==1)/*队满*/return(FALSE);if(Q-front==Q-front&&tag==0)/*x入队前队空,x入队后重新设置标志*/tag=1;Q-elememt[Q-rear]=x;Q-rear=(Q-rear+1)%MAXSIZE;/*设置队尾指针*/Return(TRUE);}出队算法:intDeleteQueue(SeqQueue*Q,QueueElementType*x){/*删除队头元素,用x返回其值*/if(Q-front==Q-rear&&tag==0)/*队空*/return(FALSE);*x=Q-element[Q-front];Q-front=(Q-front+1)%MAXSIZE;/*重新设置队头指针*/if(Q-front==Q-rear)tag=0;/*队头元素出队后队列为空,重新设置标志域*/Return(TUUE);}15(1)功能:将栈中元素倒置。(2)功能:删除栈中的e元素。(3)功能:将队列中的元素倒置。第四章1.设s=’IAMASTUDENT’,t=’GOOD’,q=’WORKER’。给出下列操作的结果:【解答】StrLength(s)=14;SubString(sub1,s,1,7)sub1=’IAMA’;SubString(sub2,s,7,1)sub2=’’;StrIndex(s,4,’A’)=6;StrReplace(s,
本文标题:数据结构课后习题
链接地址:https://www.777doc.com/doc-4296264 .html