说明:1.本文是对严蔚敏《数据结构(c语言版)习题集》一书中所有算法设计题目的解决方案,主要作者为一具.以下网友:biwier,szm99,siice,龙抬头,iamkent,zames,birdthinking,lovebuaa等为答案的修订和完善工作提出了宝贵意见,在此表示感谢;2.本解答中的所有算法均采用类c语言描述,设计原则为面向交流、面向阅读,作者不保证程序能够上机正常运行(这种保证实际上也没有任何意义);3.本解答原则上只给出源代码以及必要的注释,对于一些难度较高或思路特殊的题目将给出简要的分析说明,对于作者无法解决的题目将给出必要的讨论.目前尚未解决的题目有:5.20,10.40;4.请读者在自己已经解决了某个题目或进行了充分的思考之后,再参考本解答,以保证复习效果;5.由于作者水平所限,本解答中一定存在不少这样或者那样的错误和不足,希望读者们在阅读中多动脑、勤思考,争取发现和纠正这些错误,写出更好的算法来.请将你发现的错误或其它值得改进之处向作者报告:yi-ju@263.net第一章绪论1.16voidprint_descending(intx,inty,intz)//按从大到小顺序输出三个数{scanf(%d,%d,%d,&x,&y,&z);if(xy)x-y;//-为表示交换的双目运算符,以下同if(yz)y-z;if(xy)x-y;//冒泡排序printf(%d%d%d,x,y,z);}//print_descending1.17Statusfib(intk,intm,int&f)//求k阶斐波那契序列的第m项的值f{inttempd;if(k2||m0)returnERROR;if(mk-1)f=0;elseif(m==k-1||m==k)f=1;else{for(i=0;i=k-2;i++)temp[i]=0;temp[k-1]=1;temp[k]=1;//初始化sum=1;j=0;for(i=k+1;i=m;i++,j++)//求出序列第k至第m个元素的值temp[i]=2*sum-temp[j];f=temp[m];}returnOK;}//fib分析:k阶斐波那契序列的第m项的值f[m]=f[m-1]+f[m-2]+......+f[m-k]=f[m-1]+f[m-2]+......+f[m-k]+f[m-k-1]-f[m-k-1]=2*f[m-1]-f[m-k-1]所以上述算法的时间复杂度仅为O(m).如果采用递归设计,将达到O(k^m).即使采用暂存中间结果的方法,也将达到O(m^2).1.18typedefstruct{char*sport;enum{male,female}gender;charschoolname;//校名为'A','B','C','D'或'E'char*result;intscore;}resulttype;typedefstruct{intmalescore;intfemalescore;inttotalscore;}scoretype;voidsummary(resulttyperesult[])//求各校的男女总分和团体总分,假设结果已经储存在result[]数组中{scoretypescore[MAXSIZE];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;elsescore[0].femalescore+=result[i].score;break;case'B':score[0].totalscore+=result[i].score;if(result[i].gender==0)score[0].malescore+=result[i].score;elsescore[0].femalescore+=result[i].score;break;………………}i++;}for(i=0;i5;i++){printf(School%d:\n,i);printf(Totalscoreofmale:%d\n,score[i].malescore);printf(Totalscoreoffemale:%d\n,score[i].femalescore);printf(Totalscoreofall:%d\n\n,score[i].totalscore);}}//summary1.19Statusalgo119(inta[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))reurnOVERFLOW;last=a[i-1];returnOK;}}//algo119分析:当某一项的结果超过了maxint时,它除以前面一项的商会发生异常.1.20voidpolyvalue(){floattemp;float*p=a;printf(Inputnumberofterms:);scanf(%d,&n);printf(Inputvalueofx:);scanf(%f,&x);printf(Inputthe%dcoefficientsfroma0toa%d:\n,n+1,n);p=a;xp=1;sum=0;//xp用于存放x的i次方for(i=0;i=n;i++){scanf(%f,&temp);sum+=xp*(temp);xp*=x;}printf(Valueis:%f,sum);}//polyvalue第二章线性表2.10StatusDeleteK(SqList&a,inti,intk)//删除线性表a中第i个元素起的k个元素{if(i1||k0||i+k-1a.length)returnINFEASIBLE;for(count=1;i+count-1=a.length-k;count++)//注意循环结束的条件a.elem[i+count-1]=a.elem[i+count+k-1];a.length-=k;returnOK;}//DeleteK2.11StatusInsert_SqList(SqList&va,intx)//把x插入递增有序表va中{if(va.length+1va.listsize)returnERROR;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;returnOK;}//Insert_SqList2.12intListComp(SqListA,SqListB)//比较字符表A和B,并用返回值表示结果,值为1,表示AB;值为-1,表示AB;值为0,表示A=B{for(i=1;i=A.length&&i=B.length;i++)if(A.elem[i]!=B.elem[i])returnA.elem[i]B.elem[i]?1:-1;if(A.length==B.length)return0;returnA.lengthB.length?1:-1;//当两个字符表可以互相比较的部分完全相同时,哪个较长,哪个就较大}//ListComp2.13LNode*Locate(LinkListL,intx)//链表上的元素查找,返回指针{for(p=l-next;p&&p-data!=x;p=p-next);returnp;}//Locate2.14intLength(LinkListL)//求链表的长度{for(k=0,p=L;p-next;p=p-next,k++);returnk;}//Length2.15voidListConcat(LinkListha,LinkListhb,LinkList&hc)//把链表hb接在ha后面形成链表hc{hc=ha;p=ha;while(p-next)p=p-next;p-next=hb;}//ListConcat2.16见书后答案.2.17StatusInsert(LinkList&L,inti,intb)//在无头结点链表L的第i个元素之前插入元素b{p=L;q=(LinkList*)malloc(sizeof(LNode));q.data=b;if(i==1){q.next=p;L=q;//插入在链表头部}else{while(--i1)p=p-next;q-next=p-next;p-next=q;//插入在第i个元素的位置}}//Insert2.18StatusDelete(LinkList&L,inti)//在无头结点链表L中删除第i个元素{if(i==1)L=L-next;//删除第一个元素else{p=L;while(--i1)p=p-next;p-next=p-next-next;//删除第i个元素}}//Delete2.19StatusDelete_Between(Linklist&L,intmink,intmaxk)//删除元素递增排列的链表L中值大于mink且小于maxk的所有元素{p=L;while(p-next-data=mink)p=p-next;//p是最后一个不大于mink的元素if(p-next)//如果还有比mink更大的元素{q=p-next;while(q-datamaxk)q=q-next;//q是第一个不小于maxk的元素p-next=q;}}//Delete_Between2.20StatusDelete_Equal(Linklist&L)//删除元素递增排列的链表L中所有值相同的元素{p=L-next;q=p-next;//p,q指向相邻两元素while(p-next){if(p-data!=q-data){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.21voidreverse(SqList&A)//顺序表的就地逆置{for(i=1,j=A.length;ij;i++,j--)A.elem[i]-A.elem[j];}//reverse2.22voidLinkList_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.23voidmerge1(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.24voidreverse_mer