经典算法设计复习.docx
- 文档编号:27140140
- 上传时间:2023-06-27
- 格式:DOCX
- 页数:12
- 大小:17.49KB
经典算法设计复习.docx
《经典算法设计复习.docx》由会员分享,可在线阅读,更多相关《经典算法设计复习.docx(12页珍藏版)》请在冰豆网上搜索。
经典算法设计复习
算法设计题复习
1、设有一个顺序表L,含有2n个整数,其中n个为负数,n个为正数,设计一个算法将L中所有元素按正负数相间排列。
要求本算法的时间复杂度为O(n),空间复杂度为O
(1)
voidmove(SqList&L)
{
inti=0,j=L.length-1;
inttemp;
while(i { while(i while(i if(i { temp=L.elem[i]; L.elem[i]=L.elem[j]; L.elem[j]=temp; } } i=1; while(i { j=L.length-2; temp=L.elem[i]; L.elem[i]=L.elem[j]; L.elem[j]=temp; i=i+2; j=j-2; } } 2、有一个带头结点的单链表L(至少有一个结点),设计算法将L逆置。 StatusListOppose_L(LinkList&L) { LinkListp,q; p=L->next;//p指向单链表第一个结点 L->next=NULL;//形成空的单链表 while(p){//采用头插入法将p结点插入到头结点的后面实现逆置 q=p; p=p->next; q->next=L->next; L->next=q; } returnOK; } 3、已知指针ha和hb分别指向两个单链表的头结点,并且已知两个链表的长度分别为m和n。 试写一算法将这两个链表连接在一起,假设指针hc指向连接后的链表的头结点,并要求算法以尽可能短的时间完成连接运算。 请分析你的算法的时间复杂度。 voidMergeList_L(LinkList&ha,LinkList&hb,LinkList&hc,intm,intn){ if(m>n){ hc=hb; p=hb->next; q=ha->next; } else{ hc=ha; p=ha->next; q=hb->next; } while(p->next! =NULL) p=p->next; if(q==ha->next)free(ha);elsefree(hb); p->next=q; } 4、假设以顺序存储结构实现一个双向栈,即在一维数组的存储空间中存在着两个栈,它们的栈底分别设在数组的两个端点。 试编写实现这个双向栈tws的三个操作: 初始化inistack(tws)、入栈push(tws,i,x)和出栈pop(tws,i)的算法,其中i为0或1,用以分别指示设在数组两端的两个栈。 typedefDStack{ ElemType*top[2]; ElemType*base; intstacksize; }DStack; initstack(DStack&tws){ tws.base=(ElemType*)malloc(m*sizeof(ElemType)); if(! tws.base)exit(OVERFLOW); tws.top[0]=tws.base; tws.top[1]=tws.base+m; tws.stacksize=m; } StatusPush(DStack&tws,inti,ElemTypex) { if(tws.top[1]=tws.top[0]+1)returnERROR;//上溢 elseif(i==0){//对第一个栈入栈 *tws.top[0]=x; tws.top[0]++; } else{//对第二个栈入栈//对第二个栈入栈 *tws.top[1]=x; tws.top[1]--; } } } StatusPop((DStack&tws,inti,ElemType&x) { if(i==0){//对第一个栈出栈 if(tws.top[0]==tws.base)returnERROR; else{tws.top[0]--;x=*tws.top[0];} }else{//对第二个栈出栈 if(tws.top[1]==tws.base+m+1)returnERROR; else{tws.top[1]++;x=*tws.top[1];} } returnOK; } } 5、试写一个算法判别读入的一个以‘@’为结束符的字符序列是否是“回文”。 答: 编程如下: intPalindrome_Test()//判别输入的字符串是否回文序列,是则返回1,否则返回0 { InitStack(S);InitQueue(Q); while((c=getchar())! ='@') { Push(S,c);EnQueue(Q,c);//同时使用栈和队列两种结构 } while(! StackEmpty(S)) { Pop(S,a);DeQueue(Q,b)); if(a! =b)returnERROR; } returnOK; }//Palindrome_Test 6、用单链表表示集合,集合中的元素递增有序排列,设计算法求两个集合的交集。 要求不破坏原有的结点。 StatusListCross_L(LinkList&A,LinkList&B,LinkList&C) { pa=A->next; pb=B->next; C=(LinkList)malloc(sizeof(LNode)); C->next=NULL; r=C; while(pa&&pb){ if(pa->data pa=pa->next; else if(pa->data>pb->data) pb=pb->next; else{ s=(LinkList)malloc(sizeof(LNode)); s->data=pa->data; s->next=NULL; r->next=s;r=s; pa=pa->next;pb=pb->next; } } r->next=NULL; } 以上题目如果要求利用原有空间完成交集运算,则算法修改为: StatusListCross_L(LinkList&A,LinkList&B,LinkList&C) { C=A; pa=A->next; pb=B->next; pc=A; while(pa&&pb){ if(pa->data {q=pa;pc->next=pa->next;pa=pa->next;free(q);} elseif(pa->data>pb->data)pb=pb->next; else//pa->data=pb->data {pc=pa;pa=pa->next;pb=pb->next;} } } 7、用单链表表示集合,集合中的元素递增有序,设计算法求两个集合的并集。 要求不破坏原有的存储空间。 StatusListUnion_L(LinkList&A,LinkList&B,LinkList&C) { pa=A->next; pb=B->next; C=(LinkList)malloc(sizeof(LNode)); C->next=NULL; r=C; while(pa&&pb){ if(pa->data { s=(LinkList)malloc(sizeof(LNode)); s->data=pa->data; s->next=NULL; r->next=s;r=s; pa=pa->next; } else if(pa->data>pb->data) { s=(LinkList)malloc(sizeof(LNode)); s->data=pb->data; s->next=NULL; r->next=s;r=s; pb=pb->next; } else{ s=(LinkList)malloc(sizeof(LNode)); s->data=pa->data; s->next=NULL; r->next=s;r=s; pa=pa->next;pb=pb->next; } } while(pa) { s=(LinkList)malloc(sizeof(LNode)); s->data=pa->data; s->next=NULL; r->next=s;r=s; pa=pa->next; } while(pb) { s=(LinkList)malloc(sizeof(LNode)); s->data=pb->data; s->next=NULL; r->next=s;r=s; pb=pb->next; } r->next=NULL; } 以上题目如果要求利用原有空间完成并集,算法修改为: StatusListUnion_L(LinkList&A,LinkList&B,LinkList&C) { LinkListpa,pb,pc; pa=A->next;pb=B->next;C=pc=A;//初始化 while(pa&&pb)//将pa、pb结点按大小依次插入C中 {if(pa->data {pc->next=pa;pc=pa;pa=pa->next;} elseif(pa->data>pb->data) {pc->next=pb;pc=pb;pb=pb->next;} else {pc->next=pa;pc=pa;pa=pa->next;pb=pb->next;} } pc->next=pa? pa: pb;//插入剩余段 free(B);//释放B的头结点 } 8、顺序存储的有序表S设计折半查找的算法(递归和非递归两种方法)。 //折半查找的递归算法 intSearch_Bin_Recursive(SSTableST,intkey,intlow,inthigh) { if(low>high)return0;//查找不到时返回0 mid=(low+high)/2; if(ST.elem[mid].key==key)returnmid; elseif(ST.elem[mid].key>key) returnSearch_Bin_Recursive(ST,key,low,mid-1); elsereturnSearch_Bin_Recursive(ST,key,mid+1,high); } }//Search_Bin_Recursive //非递归 intsearch(SqListS,KeyTypex) //二分查找,返回有序表中大于等于x的元素位置 { intlow=1,high=L.length; while(low<=high) { mid=(low+high)/2; if(S.elem[mid].key==x)returnmid else if(S.elem[mid].key elselow=mid+1; } } 9.写出非递归调用的快速排序算法。 voidqksort(listA)/*n为元素个数*/ {InitStack(S);/*设置一个栈保存有关参数和变量*/ j=1;h=n;/*j,h分别指向表头和表尾*/ while((j empty(S))) {while(j {i=patition(A,j,h); push(S,j,h,i);/*保存变量值*/ h=i-1;/*设置对左边进行划分的参数*/ } if(! empty(S)) {pop(S,j,h,i);/*取出变量值*/ j=i+1;/*设置对右边进行划分的参数*/ } } } 10.插入排序中找插入位置的操作可以通过二分法查找的方法来实现。 试据此写一个改进后的插入排序方法。 voidsort(listA)/*n为元素个数,数组下标从1开始,到n结束。 */ {for(i=2;i<=n;i++) {low=1;high=i–1;/*low,high分为当前元素上、下界*/ A[0].key=A[i].key; While(low<=high) {mid=(low+high)/2; If(A[0].key<=A[mid].key)high=mid–1;/*修改上界*/ elselow=mid+1;/*修改下界*/ } for(j=i-1;j>=mid;j--)A[j+1]=A[j];/*移动数据*/ A[mid]=A[i]; } } }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 经典 算法 设计 复习