
严蔚敏数据结构题集答案.docx
129页说明: 1. 本文是对严蔚敏《数据结构(c 语言版) 习题集》一书中所有算法设计题目的解决方案,主要作者为一具.以下网友:biwier,szm99,siice,龙抬头,iamkent,zames,birdthinking,lovebuaa 等为答案的修订和完善工作提出了宝贵意见,在此表示感谢;2. 本解答中的所有算法均采用类 c 语言描述,设计原则为面向交流、面向阅读,作者不保证程序能够上机正常运行(这种保证实际上也没有任何意义);3. 本解答原则上只给出源代码以及必要的注释,对于一些难度较高或思路特殊的题目将给出简要的分析说明,对于作者无法解决的题目将给出必要的讨论.目前尚未解决的题目有: 5.20, 10.40;4. 请读者在自己已经解决了某个题目或进行了充分的思考之后,再参考本解答,以保证复习效果;5. 由于作者水平所限,本解答中一定存在不少这样或者那样的错误和不足,希望读者们在阅读中多动脑、勤思考,争取发现和纠正这些错误,写出更好的算法来.请将你发现的错误或其它值得改进之处向作者报告: yi-ju@ 第一章 绪论 1.16 void print_descending(int x,int y,int z)//按从大到小顺序输出三个数{scanf("%d,%d,%d",&x,&y,&z);if(xy; //为表示交换的双目运算符 ,以下同if(yz;if(xy; //冒泡排序printf("%d %d %d",x,y,z);}//print_descending 1.17 Status fib(int k,int m,int &f)//求 k 阶斐波那契序列的第 m 项的值 f{int tempd;if(ka.length) return INFEASIBLE;for(count=1;i+count-1va.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_SqList 2.12 int ListComp(SqList A,SqList B)//比较字符表 A 和 B,并用返回值表示结果,值为 1,表示 A>B;值为 -1,表示 AB.elem[i]?1:-1;if(A.length==B.length) return 0; return A.length>B.length?1:-1; //当两个字符表可以互相比较的部分完全相同时,哪个较长,哪个就较大}//ListComp 2.13 LNode* Locate(LinkList L,int x)//链表上的元素查找 ,返回指针{for(p=l->next;p&&p->data!=x;p=p->next);return p;}//Locate 2.14 int Length(LinkList L)//求链表的长度{for(k=0,p=L;p->next;p=p->next,k++);return k;}//Length 2.15 void ListConcat(LinkList ha,LinkList hb,LinkList &hc)//把链表 hb 接在 ha 后面形成链表 hc{hc=ha;p=ha;while(p->next) p=p->next;p->next=hb;}//ListConcat 2.16 见书后答案. 2.17 Status 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 个元素的位置}}//Insert 2.18 Status 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 个元素}}//Delete 2.19 Status Delete_Between(Linklist &L,int mink,int maxk)//删除元素递增排列的链表L 中值大于 mink 且小于 maxk 的所有元素{p=L;while(p->next->datanext; //p 是最后一个不大于 mink 的元素if(p->next) //如果还有比 mink 更大的元素{q=p->next;while(q->datanext; //q 是第一个不小于 maxk 的元素p->next=q;}}//Delete_Between 2.20 Status Delete_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_Equal 2.21 void reverse(SqList &A)//顺序表的就地逆置{for(i=1,j=A.length;iA.elem[j];}//reverse 2.22 void 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.23 void 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}//merge1 2.24 void 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){if(pa->datadata||!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.25 void 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]) j++;if(A.elem[i]==B.elem[j]){C.elem[++k]=A.elem[i]; //当发现了一个在 A,B 中都存在的元素, i++;j++; //就添加到 C 中}}//while}//SqList_Intersect 2.26 void LinkList_Intersect(LinkList A,LinkList B,LinkList &C)//在链表结构上重做上题{p=A->next;q=B->next;pc=(LNode*)malloc(sizeof(LNode)); C=pc;while(p&&q){if(p->datadata) 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;}}//while}//LinkList_Intersect 2.27 void 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]) j++;else if(A.elem[i]!=A.elem[k]){A.elem[++k]=A.elem[i]; //当发现了一个在 A,B 中都存在的元素i++;j++; //且 C 中没有,就添加到 C 中}else {i++;j++;}}//while while(A.elem[k]) A.elem[k++]=0;}//SqList_Intersect_True 2.28 void LinkList_Intersect_True(LinkList &A,LinkList B)//在链表结构上重做上题{p=A->next;q=B->next;pc=A;while(p&&q){if(p->datadata) 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_True 2.29 void SqList_Intersect_Delete(SqList &A,SqList B,SqList C) {i=0;j=0;k=0;m=0; //i 指示 A 中元素原来的位置,m 为移动后的位置while(iC.elem[k]) k++;else{same=B.elem[j]; //找到了相同元素 samewhile(B.elem[j]==same) j++;while(C.elem[k]==same) k++; //j,k 后移到新的元素while(inext;q=C->next;r=A-next;while(p&&q&&r){if(p->datadata) p=p->next;el。












