链表第二章.docx
- 文档编号:3561144
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:30
- 大小:55.64KB
链表第二章.docx
《链表第二章.docx》由会员分享,可在线阅读,更多相关《链表第二章.docx(30页珍藏版)》请在冰豆网上搜索。
链表第二章
StatusDeleteK(SqList&a,inti,intk)
{
//从顺序存储结构的线性表a中删除第i个元素起的k个元素
//注意i的编号从0开始
intj;
if(i<0||i>a.length-1||k<0||k>a.length-i)returnINFEASIBLE;
for(j=0;j<=k;j++)
a.elem[j+i]=a.elem[j+i+k];
a.length=a.length-k;
returnOK;
}
2.11设顺序表va中的数据元素递增有序。
试写一算法,将x插入到顺序表的适当位置上,以保持该表的有序性。
解:
StatusInsertOrderList(SqList&va,ElemTypex)
{
//在非递减的顺序表va中插入元素x并使其仍成为顺序表的算法
inti;
if(va.length==va.listsize)return(OVERFLOW);
for(i=va.length;i>0,x va.elem[i]=va.elem[i-1]; va.elem[i]=x; va.length++; returnOK; } 2.12设 和 均为顺序表, 和 分别为 和 中除去最大共同前缀后的子表。 若 空表,则 ;若 =空表,而 空表,或者两者均不为空表,且 的首元小于 的首元,则 ;否则 。 试写一个比较 , 大小的算法。 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 解: StatusCompareOrderList(SqList&A,SqList&B) { inti,k,j; k=A.length>B.length? A.length: B.length; for(i=0;i if(A.elem[i]>B.elem[i])j=1; if(A.elem[i] } if(A.length>k)j=1; if(B.length>k)j=-1; if(A.length==B.length)j=0; returnj; } 2.15已知指针ha和hb分别指向两个单链表的头结点,并且已知两个链表的长度分别为m和n。 试写一算法将这两个链表连接在一起,假设指针hc指向连接后的链表的头结点,并要求算法以尽可能短的时间完成连接运算。 请分析你的算法的时间复杂度。 ? ? ? ? ? ? ? 解: voidMergeList_L(LinkList&ha,LinkList&hb,LinkList&hc). { LinkListpa,pb; pa=ha; pb=hb; while(pa->next&&pb->next){ pa=pa->next; pb=pb->next; } if(! pa->next){ hc=hb; while(pb->next)pb=pb->next; pb->next=ha->next; } else{ hc=ha; while(pa->next)pa=pa->next; pa->next=hb->next; } } 2.16已知指针la和lb分别指向两个无头结点单链表中的首元结点。 下列算法是从表la中删除自第i个元素起共len个元素后,将它们插入到表lb中第j个元素之前。 解: StatusDeleteAndInsertSub(LinkList&la,LinkList&lb,inti,intj,intlen) { LinkListp,q,s,prev=NULL; intk=1; if(i<0||j<0||len<0)returnINFEASIBLE; //在la表中查找第i个结点 p=la; while(p&&k prev=p; p=p->next; k++; } if(! p)returnINFEASIBLE; //在la表中查找第i+len-1个结点 q=p;k=1; while(q&&k q=p->next; k++; } if(! q)returnINFEASIBLE; //完成删除,注意,i=1的情况需要特殊处理 if(! prev)la=q->next; elseprev->next=q->next; //将从la中删除的结点插入到lb中 if(j=1){ q->next=lb; lb=p; } else{ s=lb;k=1; while(s&&k s=s->next; k++; } if(! s)returnINFEASIBLE; q->next=s->next; s->next=p;//完成插入 } returnOK; } 2.19已知线性表中的元素以值递增有序排列,并以单链表作存储结构。 试写一高效的算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素),同时释放被删结点空间,并分析你的算法的时间复杂度(注意,mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。 解: StatusListDelete_L(LinkList&L,ElemTypemink,ElemTypemaxk) { LinkListp,q,prev=NULL; if(mink>maxk)returnERROR; p=L; prev=p; p=p->next; while(p&&p->data if(p->data<=mink){ prev=p; p=p->next; } else{ prev->next=p->next; q=p; p=p->next; free(q); } } returnOK; } 2.20同2.19题条件,试写一高效的算法,删除表中所有值相同的多余元素(使得操作后的线性表中所有元素的值均不相同),同时释放被删结点空间,并分析你的算法的时间复杂度。 解: voidListDelete_LSameNode(LinkList&L) { LinkListp,q,prev; p=L; prev=p; p=p->next; while(p){ prev=p; p=p->next; if(p&&p->data==prev->data){ prev->next=p->next; q=p; p=p->next; free(q); } } } 2.22试写一算法,对单链表实现就地逆置。 解: //带头结点的单链表的逆置 StatusListOppose_L(LinkList&L) { LinkListp,q; p=L; p=p->next; L->next=NULL; while(p){ q=p; p=p->next; q->next=L->next; L->next=q; } returnOK; } 2.23设线性表 , ,试写一个按下列规则合并A,B为线性表C的算法,即使得 当 时; 当 时。 线性表A,B和C均以单链表作存储结构,且C表利用A表和B表中的结点空间构成。 注意: 单链表的长度值m和n均未显式存储。 解: //将合并后的结果放在C表中,并删除B表 StatusListMerge_L(LinkList&A,LinkList&B,LinkList&C) { LinkListpa,pb,qa,qb; pa=A->next; pb=B->next; C=A; while(pa&&pb){ qa=pa;qb=pb; pa=pa->next;pb=pb->next; qb->next=qa->next; qa->next=qb; } if(! pa)qb->next=pb; pb=B; free(pb); returnOK; } 2.24假设有两个按元素值递增有序排列的线性表A和B,均以单链表作存储结构,请编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许表中含有值相同的元素)排列的线性表C,并要求利用原表(即A表和B表)的结点空间构造C表。 解: //将合并逆置后的结果放在C表中,并删除B表 StatusListMergeOppose_L(LinkList&A,LinkList&B,LinkList&C) { LinkListpa,pb,qa,qb; pa=A; pb=B; qa=pa;//保存pa的前驱指针 qb=pb;//保存pb的前驱指针 pa=pa->next; pb=pb->next; A->next=NULL; C=A; while(pa&&pb){ if(pa->data qa=pa; pa=pa->next; qa->next=A->next;//将当前最小结点插入A表表头 A->next=qa; } else{ qb=pb; pb=pb->next; qb->next=A->next;//将当前最小结点插入A表表头 A->next=qb; } } while(pa){ qa=pa; pa=pa->next; qa->next=A->next; A->next=qa; } while(pb){ qb=pb; pb=pb->next; qb->next=A->next; A->next=qb; } pb=B; free(pb); returnOK; } 2.25假设以两个元素依值递增有序排列的线性表A和B分别表示两个集合(即同一表中的元素值各不相同),现要求另辟空间构成一个线性表C,其元素为A和B中元素的交集,且表C中的元素有依值递增有序排列。 试对顺序表编写求C的算法。 解: //将A、B求交后的结果放在C表中 StatusListCross_Sq(SqList&A,SqList&B,SqList&C) { inti=0,j=0,k=0; while(i if(A.elem[i] else if(A.elem[i]>B.elem[j])j++; else{ ListInsert_Sq(C,k,A.elem[i]); i++; k++; } } returnOK; } 2.26要求同2.25题。 试对单链表编写求C的算法。 解: //将A、B求交后的结果放在C表中,并删除B表 StatusListCross_L(LinkList&A,LinkList&B,LinkList&C) { LinkListpa,pb,qa,qb,pt; pa=A; pb=B; qa=pa;//保存pa的前驱指针 qb=pb;//保存pb的前驱指针 pa=pa->next; pb=pb->next; C=A; while(pa&&pb){ if(pa->data pt=pa; pa=pa->next; qa->next=pa; free(pt); } else if(pa->data>pb->data){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } else{ qa=pa; pa=pa->next; } } while(pa){ pt=pa; pa=pa->next; qa->next=pa; free(pt); } while(pb){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } pb=B; free(pb); returnOK; } 2.27对2.25题的条件作以下两点修改,对顺序表重新编写求得表C的算法。 (1)假设在同一表(A或B)中可能存在值相同的元素,但要求新生成的表C中的元素值各不相同; (2)利用A表空间存放表C。 解: (1) //A、B求交,然后删除相同元素,将结果放在C表中 StatusListCrossDelSame_Sq(SqList&A,SqList&B,SqList&C) { inti=0,j=0,k=0; while(i if(A.elem[i] else if(A.elem[i]>B.elem[j])j++; else { if(C.length==0) { ListInsert_Sq(C,k,A.elem[i]); k++; } else if(C.elem[C.length-1]! =A.elem[i]) { ListInsert_Sq(C,k,A.elem[i]); k++; } i++; } } returnOK; } (2) //A、B求交,然后删除相同元素,将结果放在A表中 StatusListCrossDelSame_Sq(SqList&A,SqList&B) { inti=0,j=0,k=0; while(i if(A.elem[i] else if(A.elem[i]>B.elem[j])j++; else{ if(k==0){ A.elem[k]=A.elem[i]; k++; } else if(A.elem[k]! =A.elem[i]){ A.elem[k]=A.elem[i]; k++; } i++; } } A.length=k; returnOK; } 2.28对2.25题的条件作以下两点修改,对单链表重新编写求得表C的算法。 (1)假设在同一表(A或B)中可能存在值相同的元素,但要求新生成的表C中的元素值各不相同; (2)利用原表(A表或B表)中的结点构成表C,并释放A表中的无用结点空间。 解: (1) //A、B求交,结果放在C表中,并删除相同元素 StatusListCrossDelSame_L(LinkList&A,LinkList&B,LinkList&C) { LinkListpa,pb,qa,qb,pt; pa=A; pb=B; qa=pa;//保存pa的前驱指针 qb=pb;//保存pb的前驱指针 pa=pa->next; pb=pb->next; C=A; while(pa&&pb){ if(pa->data pt=pa; pa=pa->next; qa->next=pa; free(pt); } else if(pa->data>pb->data){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } else{ if(pa->data==qa->data){ pt=pa; pa=pa->next; qa->next=pa; free(pt); } else{ qa=pa; pa=pa->next; } } } while(pa){ pt=pa; pa=pa->next; qa->next=pa; free(pt); } while(pb){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } pb=B; free(pb); returnOK; } (2) //A、B求交,结果放在A表中,并删除相同元素 StatusListCrossDelSame_L(LinkList&A,LinkList&B) { LinkListpa,pb,qa,qb,pt; pa=A; pb=B; qa=pa;//保存pa的前驱指针 qb=pb;//保存pb的前驱指针 pa=pa->next; pb=pb->next; while(pa&&pb){ if(pa->data pt=pa; pa=pa->next; qa->next=pa; free(pt); } else if(pa->data>pb->data){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } else{ if(pa->data==qa->data){ pt=pa; pa=pa->next; qa->next=pa; free(pt); } else{ qa=pa; pa=pa->next; } } } while(pa){ pt=pa; pa=pa->next; qa->next=pa; free(pt); } while(pb){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } pb=B; free(pb); returnOK; } 2.29已知A,B和C为三个递增有序的线性表,现要求对A表作如下操作: 删去那些既在B表中出现又在C表中出现的元素。 试对顺序表编写实现上述操作的算法,并分析你的算法的时间复杂度(注意: 题中没有特别指明同一表中的元素值各不相同)。 解: //在A中删除既在B中出现又在C中出现的元素,结果放在D中 StatusListUnion_Sq(SqList&D,SqList&A,SqList&B,SqList&C) { SqListTemp; InitList_Sq(Temp); ListCross_L(B,C,Temp); ListMinus_L(A,Temp,D); } 2.30要求同2.29题。 试对单链表编写算法,请释放A表中的无用结点空间。 解: //在A中删除既在B中出现又在C中出现的元素,并释放B、C StatusListUnion_L(LinkList&A,LinkList&B,LinkList&C) { ListCross_L(B,C); ListMinus_L(A,B); } //求集合A-B,结果放在A表中,并删除B表 StatusListMinus_L(LinkList&A,LinkList&B) { LinkListpa,pb,qa,qb,pt; pa=A; pb=B; qa=pa;//保存pa的前驱指针 qb=pb;//保存pb的前驱指针 pa=pa->next; pb=pb->next; while(pa&&pb){ if(pb->data pt=pb; pb=pb->next; qb->next=pb; free(pt); } else if(pb->data>pa->data){ qa=pa; pa=pa->next; } else{ pt=pa; pa=pa->next; qa->next=pa; free(pt); } } while(pb){ pt=pb; pb=pb->next; qb->next=pb; free(pt); } pb=B; free(pb); returnOK; } 2.31假设某个单向循环链表的长度大于1,且表中既无头结点也无头指针。 已知s为指向链表中某个结点的指针,试编写算法在链表中删除指针s所指结点的前驱结点。 解: //在单循环链表S中删除S的前驱结点 StatusListDelete_CL(LinkList&S) { LinkListp,q; if(S==S->next)returnERROR; q=S; p=S->next; while(p->next! =S){ q=p; p=p->next; } q->next=p->next; free(p); returnOK; } 2.32已知有一个单向循环链表,其每个结点中含三个域: pre,data和next,其中data为数据域,next为指向后继结点的指针域,pre也为指针域,但它的值为空,试编写算法将此单向循环链表改为双向循环链表,即使pre成为指向前驱结点的指针域。 解: //建立一个空的循环链表 StatusInitList_DL(DuLinkList&L) { L=(DuLinkList)malloc(sizeof(DuLNode)); if(! L)exit(OVERFLOW); L->pre=NULL; L->next=L; returnOK; } //向循环链表中插入一个结点 StatusListInsert_DL(DuLinkList&L,ElemTypee) { DuLinkListp; p=(DuLinkList)malloc(sizeof(DuLNode)); if(! p)returnERROR;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 第二