北邮算法与数据结构习题参考答案.docx
- 文档编号:26072835
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:22
- 大小:74.97KB
北邮算法与数据结构习题参考答案.docx
《北邮算法与数据结构习题参考答案.docx》由会员分享,可在线阅读,更多相关《北邮算法与数据结构习题参考答案.docx(22页珍藏版)》请在冰豆网上搜索。
北邮算法与数据结构习题参考答案
北邮算法与数据结构习题参考答案
作业参考答案
一、(带头结点)多项式乘法C=A×B:
voidPolyAdd(list&C,listR)//R为单个结点
{
p=C;
while((!
p->next)&&(p->next->exp>R->exp))p=p->next;
if((p->next)||(p->next->exp
{R->next=p->next;p->next=R;}else
{p->next->inf+=R->inf;deleteR;
if(!
p->next->inf)
{R=p->next;p->next=R->next;deleteR;}
}
}
voidPolyMul(listA,listB,list&C)
{
C=newstructnode;C->next=NULL;q=B->next;
While(q)
{
p=A->next;
while(p)
{
r=newstructnode;r->exp=p->exp+q->exp;
r->inf=p->inf*q->inf;PolyAdd(C,r);
p=p->next;
}
q=q->next;
}
}
二、梵塔的移动次数:
已知移动次数迭代公式为:
M(n)=2M(n-1)+1
初值为:
M(0)=0
则:
M(n)=2(2M(n-2)+1)+1
=4M(n-2)+3
=8M(n-3)+7
=2iM(n-i)+2i–1
若n=i,则M(n-n)=0,故:
M(n)=2nM(n-n)+2n–1
=2n–1
所以,梵塔的移动次数为2n–1次。
三、简化的背包问题:
voidPack(intm,inti,intt)//初始值为:
11t
{
for(k=i;k<=n;k++)
{
solution[m]=weight[k];
if(t==weight[k])
{
for(j=1;j<=m;j++)cout< }elseif(t>weight[k])Pack(m+1,k+1,t-weight[k]); } } 四、判断括号是否配对: intCorrect(strings) { Inistack(Q); for(i=0;s[i]==‘=’;i++)//表达式以‘=’结束 { switch(s[i]) { case‘(’: case‘[’: case‘{’: Push(Q,s[i]);break; case‘)’: case‘]’: case‘}’: if(Empty(Q))return0;t=Pop(Q); if(! Matching(t,s[i]))return0; } } if(! Empty(Q))return0; return1; } 五、堆栈可能的输出: 123412431324134214231432 213421432314234124132431 312431423214324134123421 412341324213423143124321 六、用两个堆栈实现一个队列: intFullQ() { if(Full(S1)&&! Empty(S2))return1;return0; } intEmptyQ() { if(Empty(S1)&&Empty(S2))return1;return0; } voidEnqueue(elemtypex) { if(Full(S1))if(Empty(S2))while(! Empty(S1))Push(S2,Pop(S1)); if(! Full(S1))Push(S1,x); } elemtypeDequeue() { if(Empty(S2))while(! Empty(S1))Push(S2,Pop(S1)); if(! Empty(S2))returnPop(S2); } 七、生成新串及字符第一次出现位置: intIndex(stringS,stringT) { for(i=1;i+Len(T)-1<=Len(S);i++) ifEqual(Sub(S,I,Len(T)),T)returni; return0; } voidCreatNewStr(stringS,stringT,stringR,arrantP) { R=“”;j=0; for(i=1;i<=Len(S);i++) { ch=Sub(S,i,1); if(! Index(T,ch)&&! Index(R,ch)) {R=Concat(R,ch);P[j++]=i;} } } 八、块链字符串插入: {为避免字符串内部块间大量的数据移动,最好的方法是定义两种 字符串中不出现的字符作为空标记和串结束标记,如‘#’和‘$’; 也可只使用空标记,串结束以块尾指针为空表示,其算法如下: voidInsert(stringS,stringT,charch)//设块大小为m { i=0;p=T; while((p->next)&&(! i)) { for(j=1;j<=m;j++)if(p->str[j]==ch)i=j; if(! i)p=p->next; } if(! i)for(j=1;j<=m;j++)if(p->str[j]==ch)i=j; if(! i)p->next=S;else//S插在T后 {//ch所在结点分裂,S插在T中分裂的两结点间 q=newstructnode;q->str=p->str;q->next=p->next; for(j=i;j<=m;j++)p->str[j]=‘#’;p->next=S; for(j=1;jstr[j]=‘#’;p=S; while(p->next)p=p->next;p->next=q; } } 九、上三角矩阵的存储: k=(i-1)*n+j-i*(i-1)/2=(2n-i+1)*i/2+j-n f1=(2n-i+1)*i/2 f2=j c=-n 十、循环右移k位: 12345678(n=8,k=3) 67812345 87654321 voidExch(arrtypeA,intst,inted) { for(i=st;i<=(st+ed)/2;i++)A[i]←→A[ed-i+1]; } voidShift(arrtypeA,intk,intn) { Exch(A,1,n); Exch(A,1,k); Exch(A,k+1,n) } 十一、广义表运算结果: 1、(a,b)2、((c,d))3、(c,d)4、(b)5、b6、(d) 十二、利用广义表运算取出c原子: 1、Head(Tail(Tail(L1))) 2、Head(Head(Tail(L2))) 3、Head(Head(Tail(Tail(Head(L3))))) 4、Head(Head(Head(Tail(Tail(L4))))) 5、Head(Head(Tail(Tail(L5)))) 6、Head(Tail(Head(L6))) 7、Head(Head(Tail(Head(Tail(L7))))) 8、Head(Head(Tail(Head(Tail(L8))))) 十三、满k叉树问题: 1、kn-12、n=1无父结点,否则为 3、(n-1)k+1+i4、(n-1)Modk≠0 十四、叶子结点数目: n0=∑(i-1)ni+1 十五、找最近共同祖先: bitptrForefather(bitptrroot,bitptrp,bitptrq) { find=0;//0---p、q都未找到;>0---找到一个;-1---都找到了 INIT(ff);{定义一个数组ff用于记录查找路径} Fff(root,p,q,0,ft); returnft; } voidFff(bitptrroot,bitptrp,bitptrq,intm,bitptr&ft) { if(root&&(find>=0)) { m=m+1; if((root==p)||(root==q))if(! find)find=m-1;else { ft=ff[find]; find=-1; } ff[m]=root; Fff(root->lc,p,q,m,ft); Fff(root->rc,p,q,m,ft); if(m==find)find=m-1; } } 十六、求树的直径等: voidHigh(bitptrt,int*hi,Arrtypepath) { *hi=0; INIT(p);{定义数组p动态存储路径} Hhh(t,1,hi,path); } voidHhh(bitptrt,intlevel,int*hi,Arrtypepath) { if(t) { p[level]=t->data; if(! t->lc&&! t->rc)if(level>hi) { hi=level; for(i=1;i<=level;i++)path[i]=p[i]; } Hhh(t->lc,level+1,hi,path); Hhh(t->rc,level+1,hi,path); } } 十七、输出中缀表达式并加上括号: voidExpout(treet) { if(! t) { if(t->lchild)if(((t->lchild->data==‘+’)||(t->lchild->data==‘-’)) &&((t->data==‘*’)||(t->data==‘/’))) { cout<<‘(’;Expout(t->lchild);cout<<‘)’; }elseExpout(t->lchild); cout< if(t->rchild)if((t->data==‘*’)||(t->data==‘/’)) { cout<<‘(’;Expout(t->rchild);cout<<‘)’; }elseExpout(t->rchild); } } 十八、建立二叉树: voidCreat_bintree(bitptr&t,inti,strings) {//i为输入字符串的当前指针,初值为1} if(s[i]==’#’) { t=NULL; i++; }else { t=newstructnode; t->data=s[i]; i++; if((i>Length(s))||(s[i]! =‘(’)) { t->lc=t->rc=NULL; return; } i++;{去左括号} Creat_bintree(t->lc,i,s);{建左子树} i++;{去逗号} Creat_bintree(t->rc,i,s);{建右子树} i++;{去右括号} } } 十九、按凹入表方式打印树: voidPrint_tree(bitptrt) { Prt(t,1) } voidPrt(bitptrt,intlevel) { if(t) { Prt(t->rc,level+1); for(inti=1;i<=level;i++)cout<<‘’; cout< Prt(t->lc,level); } } 二十、判断是否存在长度为k的简单路经: voidSearchPath(intv,intvt,intk,intm) {//存储结构可选用邻接矩阵,路径从vs出发,到vt结束,长度为k visited[v]=TRUE; P[m]=v; if(v==vt) { if(m==k+1) { for(i=1;i<=m;i++)cout< cout< } }else { w=FirstAdj(v); while(w) { if(! visited[w])SearchPath(w,vt,k,m+1); w=NextAdj(v,w); } } visited[v]=FALSE; } 二十一、求所有简单回路: voidSearchCycle(intv,intm) {//存储结构可选用邻接矩阵 visited[v]=TRUE; P[m]=v; w=FirstAdj(v); while(w) { if(! visited[w])SearchCycle(w,m+1);else { for(j=1;P[j]==w;j++); for(i=j;i<=m;i++)cout< cout< } w=NextAdj(v,w); } visited[v]=FALSE; } 二十二、求最小代价生成树: 1、023∞∞∞∞∞ 20∞2∞∞∞∞ 3∞01∞∞∞∞ ∞21024∞∞ ∞∞∞2012∞ ∞∞∞41021 ∞∞∞∞2203 ∞∞∞∞∞130 2、 二十三、求关键路经和最短路经: 1、abcdefghi ve: 02361110131417 vl: 04361110131517 关键路经为: acdfegi 2、a→bcdefghi 2(ab)3(ac)∞∞∞∞∞∞ 3(ac)4(abd)∞∞∞∞∞ 4(abd)∞∞∞∞∞ 7(abde)8(abdf)∞∞∞ 8(abdf)9(abdeg)∞∞ 9(abdeg)9(abdfh)∞ 9(abdfh)13(abdegi) 11(abdfhi) 二十四、边界标识法: 1、 2、 二十五、按访问频度查找: listSearch(listH,keytypeK) { p=H; q=NULL; while(p->next&&! q) { if(p->next->key==K) { q=p->next; q->freq++; while((H! =p)&&(H->next->freq>=q->freq))H=H->next; if(H! =p) { p->next=q->next; q->next=H->next; H->next=q; } } p=p->next; } returnq; } 二十六、判断是否二叉排序树: intBST(bitptrt,bitptr&p) { if(! t)return1; L=BST(t->lc,p); D=1; if(p&&p->data>t->data)elseD=0; p=t; R=BST(t->rc,p); returnL&&D&&R; } intBinarySortTree(bitptrt) { p=NULL; returnBST(t,p); } 二十七、建立2-3树: 插入20插入30插入50 插入52插入60插入68 插入70删除50删除68 二十八、散列表: (1): 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Apr Aug Dec Feb Jan Mar May Jun Jul Sep Oct Nov 1+2+1+1+1+1+2+4+5+2+5+631 ASL成功=——————————————=—— 1212 5+4+3+2+1+9+8+7+6+5+4+3+2+130 ASL不成功=————————————————=—— 147 (2): 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ ∧ AprDecFebJanMarOctSep AugJunMayNov Jul 1+2+1+1+1+2+3+1+2+1+2+19 ASL成功=——————————————=—— 126 3+1+2+2+1+4+3+3+1+2+1+1+1+113 ASL不成功=————————————————=—— 147 ASL不成功=12/14(与空指针比较次数不算)? 二十九、证明快速排序退化时的时间复杂度: 当待排序列有序时,有T(n)=T(n–1)+n–1 =T(n–2)+2*n–3 =T(n–3)+3*n–6 … =T(n–i)+i*n–i*(i+1)/2 … =T(n–n)+n*n–n*(n+1)/2 =n*(n–1)/2 故,此时快速排序的时间复杂度为O(n2)。 三十、单链表存储结构的简单插入排序: voidInsertSort(pointer&r) { H=newstructnode; H->next=r; r=r->next; H->next->next=NULL; while(r) { p=r; r=r->next; q=H; while(q->next&&(p->data>q->next->data))q=q->next; p->next=q->next; q->next=p; } r=H->next; deleteH; } 三十一、计数排序: voidCountSort(listA) { for(i=1;i<=n;i++) { C[i]=0; for(j=1;j<=n;j++)if(A[i]>A[j])C[i]++; } for(i=1;i<=n;i++)B[C[i]+1]=A[i]; for(i=1;i<=n;i++)A[i]=B[i]; } 三十二、求前k个元素: 即部分排序即可得到所需结果的方法有: 1、冒泡排序: 比较次数为(n-1)+(n-2)+…+(n-k)=nk-k(k+1)/2; 2、简单选择排序: 比较次数同上,为nk-k(k+1)/2; 3、 树形排序: 需附加2n-1个空间,比较次数为(n-1)+(k-1)log2n; 4、 堆排序: 比较次数为<4n+(k-1)log2n; 5、快速排序: 比较次数为<2n。 三十三、求最大最小元素: 若不增加存储空间,则用下法,最多比较次数为2n-3次: if(r[1] { min=r[1];max=r[2]; }else { min=r[2];max=r[1]; } for(i=3;i<=n;i++)if(r[i]>max)max=r[i]; elseif(r[i] 若能增加空间,则可先将记录两两比较,将较大的和较小的记录分别存储在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 数据结构 习题 参考答案