算法作业和期末复习题Word格式.docx
《算法作业和期末复习题Word格式.docx》由会员分享,可在线阅读,更多相关《算法作业和期末复习题Word格式.docx(10页珍藏版)》请在冰豆网上搜索。
![算法作业和期末复习题Word格式.docx](https://file1.bdocx.com/fileroot1/2023-1/4/d687ff36-a2d1-468b-9aea-b9a77213d945/d687ff36-a2d1-468b-9aea-b9a77213d9451.gif)
在排序问题中,分治法用用快速排序,以轴值为基准划分序列,再求每个子集递归序列,最后合并并操作。
减治法则用选择问题算法,先选定轴值并划分,比轴值小的在左侧,比轴值大的在右侧,选择问题的查找区间减少一半,划分后只需处理一个子序列。
8.简述什么是欧拉回路,TSP问题,哈密顿回路问题。
欧拉回路:
图G的一个回路,若它恰它通过G中每条边一次,则称该回路为欧拉回路。
TSP:
从图的一个顶点出发,各个定点只能经历并访问一次,最后回到原点且使路径最短。
哈密顿回路:
从一个城市出发,经过每一个城市恰好一次,然后回到出发城市。
1.给出应用动态规划法设计算法的一般步骤,并用动态规划法求下面多段图中从顶点0到顶点15的最短路径,写出求解过程。
d(0,9)=min{c01+d(1,9),c02+d(2,9),c03+d(3,9)}
d(1,9)=min{c14+d(4,9),c15+d(5,9)}
d(2,9)=min{c24+d(4,9),c25+d(5,9),c26+d(6,9)}
d(3,9)=min{c35+d(5,9),c36+d(6,9)}
d(4,9)=min{c47+d(7,9),c48+d(8,9)}
d(5,9)=min{c57+d(7,9),c58+d(8,9)}
d(0,9)=min{c67+d(7,9),c68+d(8,9)}
d(7,9)=c79=7(7→9)
d(8,9)=c89=3(8→9)
d(6,9)=min{6+7,5+3}=8(6→8)
d(5,9)=min{8+7,6+3}=9(5→8)
d(4,9)=min{5+7,6+3}=9(4→8)
d(3,9)=min{4+9,7+8}=13(3→5)
d(2,9)=min{6+9,7+9,8+8}=15(2→4)
d(1,9)=min{9+9,8+9}=17(1→5)
d(0,9)=min{4+17,2+15,3+13}=16(0→3)
最后得最短路径为0→3→5→8→9长度为16。
2.有4个物品,其重量分别为(4,7,5,3),物品的价值分别为(40,42,25,12),背包容量为10。
试设计3种贪心策略,并给出在每种贪心策略下背包问题的解。
重量最轻:
装入143.总价值:
40+12+25*3/5=67
价值最大:
装入1,2。
总价值:
40*3/4+42=72
性价比最小:
装入1,2.总价值:
40+6/7*42=76
3.给出{2313496311928}采用快速排序思想进行排序时一次划分的过程示意图。
1913496312328
1913236314928
1913623314928
1.给定数组A[n],存储n个实数,试设计一个算法,在最坏情况下用最少比较次数找出该数组中元素的最大值和最小值,并说明采用了何种算法设计思想,其最坏比较多少次。
求数组的最大值和最小值
a)问题
求给定数组a[0:
n-1]的最大值和最小值。
要求:
最坏情况下用3n/2-2次比较
b)分析
分治法,把数组分成n/2组,每组2个数。
然后每组的两个数进行一次比较,确定出每组的最大数和最小数保存在数组MAX[i]和MIN[i]中,这样总共进行了n/2次比较。
最后从MAX[i]中找出最大的数MAX,从MIN[i]中找出最小的数MIN,需要2*(n/2-1)次比较。
MAX和MIN就是原来问题的解。
总比较次数为3n/2–2次
该算法在任何情况下进行的比较次数都是3n/2–2,固最差情况也是3n/2–2.
c)编程实现
Quotedfrom求数组的最大值和最小值:
//two15.java
//该算法在任何情况下的比较次数都是3N/2-2。
所以在最差情况下也是3N/2-2
importjavax.swing.JOptionPane;
publicclasstwo15{
publicstaticvoidmain(Stringargs[])
{inta[]=newint[50];
//
intmin[]=newint[25];
intmax[]=newint[25];
intn=0,i=0,k=1;
Stringnum;
Stringaa[]=newString[50];
num=JOptionPane.showInputDialog("
enterthetotalnumofthearray"
);
n=Integer.parseInt(num);
//单个数不进行比较
if(n!
=1){
for(i=0;
i<
n;
i++)
{aa[i]=JOptionPane.showInputDialog("
请输入数组的每个元素"
a[i]=Integer.parseInt(aa[i]);
}
//用分治法把N个数分成2/N组每组两个进行比较,把小的放在MIN,大的放在MAX
//最差情况下比较N/2次
for(i=1;
(n/2)*2;
i=i+2)
{
if(a[i-1]<
=a[i])
min[k-1]=a[i-1];
max[k-1]=a[i];
k++;
}else
{min[k-1]=a[i];
max[k-1]=a[i-1];
}}
/*在MAX中找出最大的,在MIN中找出最小的
*最差情况下比较2*(N/2-1)次*/
intmaxm=max[0],minm=min[0];
for(k=1;
k<
n/2;
k++)
if(max[k]>
maxm)maxm=max[k];
if(min[k]<
minm)minm=min[k];
}
if(n%2!
=0)//N为奇数时,还要和最后一个数比较
{if(a[n-1]>
maxm)maxm=a[n-1];
if(a[n-1]<
minm)minm=a[n-1];
JOptionPane.showMessageDialog(null,
"
最大的数是"
+maxm+"
最小的数是"
+minm,
result"
JOptionPane.INFORMATION_MESSAGE);
}
elseJOptionPane.showMessageDialog(null,
一个数无须查找"
"
警告!
2.描述贪心法的求解过程,给出基于最近邻点策略采用贪心法求解TSP问题伪代码,并分析该算法的时间性能。
伪代码:
1.P={};
2.V=V-{u0};
u=u0;
//从顶点u0出发;
3循环直到集合P中包含n-1条边3.1查找与顶点u邻接的最小代价边(u,v)并且v属于集合V;
3.2P=P+{(u,v)};
3.3V=V—{v};
3.4u=v;
//从顶点v出发继续求解
3.设计算法实现求数组中相差最小的两个元素(称为最接近数)的差。
算法MinDistance(A[0..n-1])
//输入:
数组A[0..n-1]
//输出:
thesmallestdistancedbetweentwoofitselements
算法4.10——最近对问题
intClosestPoints(S)//S为平面上n个点的坐标组成的集合
{1.if(n<
2)return∞;
2.m=S中各点x坐标的中位数;
3.构造S1和S2,使得S1中点的x坐标小于m,S2中点的x坐标大于m;
4.d1=ClosestPoints(S1);
d2=ClosestPoints(S2);
5.d=min(d1,d2);
6.构造P1和P2,使得P1是S1中点的x坐标与m的距离小于d的点集,P2是S2中点的x坐标与m的距离小于d的点集;
7.将P1和P2中的点按y坐标升序排列;
8.对P1中的每一个点p,在P2中查找与点p的y坐标小于d的点,并求出其中的最小距离d'
;
9.returnmin(d,d'
);
4.有n枚硬币,其中有一枚硬币是假币,且假币的重量较轻,通过一架天平找出假币,。
。
比较次数最少。
答:
减治算法。
先把n枚硬币分成两组,每组有[2/n]枚硬币,如果n为奇数就留下一枚硬币,然后把两组硬币分别放到天平的两端。
如果两组硬币重量相同,那么留下的硬币就是假币;
否则,用同样的方法对较轻的那组硬币进行同样处理,应为假币一定在较轻的那组里.
#include<
iostream>
cstdlib>
usingnamespacestd;
intCheck_out(intB[],intn);
intmain()
{intn,n1;
cout<
<
注意:
\n"
真硬币用1表示,假硬币用0或2表示.\n"
;
0表示假硬币比真硬币轻,2表示假硬币比真硬币重。
请输入硬币的总个数:
(请确定你输入的总个数大于2,否则不能判断出假的硬币)\n"
cin>
>
int*B=newint[n];
请输入硬币:
for(inti=0;
{cin>
n1;
while(n1!
=0&
&
n1!
=2&
=1)
{cout<
对不起,你的输入有误,请重新输入:
}B[i]=n1;
}if((B[0]+B[1]+B[2])==(B[3]+B[4]+B[5]))
{if(B[0]==B[6])
第8枚是假币"
//鏁扮粍涓槸con[7]}
else{cout<
第7枚是假币"
}else{if((B[0]+B[1])==(B[2]+B[6]))
{if((B[3]+B[4])==(B[7]+B[6]))
{cout<
第6枚是假币"
}else
{if(B[3]==B[6])
第5枚是假币"
}else
第4枚是假币"
}}}
else{if((B[0]+B[1])==(B[7]+B[6]))
第3枚是假币"
{if(B[0]==B[6]){
第2枚是假币"
}else{
第1枚是假币"
}}}}
system("
PAUSE"
returnEXIT_SUCCESS}
5.一个农夫带着一条狼、一只羊和一筐菜。
并设计算法求解。
带羊到对岸,空手回本岸,带狼到对岸,带羊回本岸,带菜到对岸,空手回本岸,带羊到对岸
stdio.h>
stdlib.h>
string.h>
#defineMAX_STEP20
//index:
0-狼,1-羊,2-菜,3-农夫,value:
0-本岸,1-对岸
inta[MAX_STEP][4];
intb[MAX_STEP];
char*name[]=
{"
空手"
"
狼"
带羊"
带菜"
};
voidsearch(intiStep)
{inti;
if(a[iStep][0]+a[iStep][1]+a[iStep][2]+a[iStep][3]==4)
{for(i=0;
i<
iStep;
i++)
{if(a[i][3]==0)
{printf("
%s到对岸\n"
name[b[i]+1]);
}else
%s回本岸\n"
}
}printf("
return;
}for(i=0;
{if(memcmp(a[i],a[iStep],sizeof(a[i]))==0)
{return;
}if(a[iStep][1]!
=a[iStep][3]&
(a[iStep][2]==a[iStep][1]||a[iStep][0]==a[iStep][1]))
}for(i=-1;
=2;
{b[iStep]=i;
memcpy(a[iStep+1],a[iStep],sizeof(a[iStep+1]));
a[iStep+1][3]=1-a[iStep+1][3];
if(i==-1)
{search(iStep+1);
}elseif(a[iStep][i]==a[iStep][3])
{a[iStep+1][i]=a[iStep+1][3];
search(iStep+1);
}}}intmain(){search(0);
return0;
6.已知某系统在通信联络中只可能出现八种字符,其概率分别为0.05,0.29,0.07,0.08,0.14,0.23,0.03,0.11,试设计其哈夫曼编码,并请画出其图形,说明其设计思想。
#defineN50/*叶子结点数*/
#defineM2*N-1/*树中结点总数*/
typedefstruct
{chardata[5];
/*结点值*/
intweight;
/*权重*/
intparent;
/*双亲结点*/
intlchild;
/*左孩子结点*/
intrchild;
/*右孩子结点*/
}HTNode;
{charcd[N];
/*存放哈夫曼码*/
intstart;
}HCode;
voidCreateHT(HTNodeht[],intn)
{inti,k,lnode,rnode;
intmin1,min2;
for(i=0;
2*n-1;
i++)/*所有结点的相关域置初值-1*/
ht[i].parent=ht[i].lchild=ht[i].rchild=-1;
for(i=n;
i++)/*构造哈夫曼树*/
{min1=min2=32767;
/*lnode和rnode为最小权重的两个结点位置*/
lnode=rnode=-1;
for(k=0;
=i-1;
if(ht[k].parent==-1)/*只在尚未构造二叉树的结点中查找*/{if(ht[k].weight<
min1)
{min2=min1;
rnode=lnode;
min1=ht[k].weight;
lnode=k;
elseif(ht[k].weight<
min2)
{min2=ht[k].weight;
rnode=k;
ht[lnode].parent=i;
ht[rnode].parent=i;
ht[i].weight=ht[lnode].weight+ht[rnode].weight;
ht[i].lchild=lnode;
ht[i].rchild=rnode;
}}
voidCreateHCode(HTNodeht[],HCodehcd[],intn)
{inti,f,c;
HCodehc;
i++)/*根据哈夫曼树求哈夫曼编码*/
{hc.start=n;
c=i;
f=ht[i].parent;
while(f!
=-1)/*循序直到树根结点*/{
if(ht[f].lchild==c)//处理左孩子结点
hc.cd[hc.start--]='
0'
else/*处理右孩子结点*/
1'
c=f;
f=ht[f].parent;
hc.start++;
/*start指向哈夫曼编码最开始字符*/
hcd[i]=hc}}
voidDispHCode(HTNodeht[],HCodehcd[],intn)
{inti,k;
intsum=0,m=0,j;
printf("
输出哈夫曼编码:
/*输出哈夫曼编码*/
{j=0;
%s:
\t"
ht[i].data);
for(k=hcd[i].start;
=n;
{printf("
%c"
hcd[i].cd[k]);
j++;
m+=ht[i].weight;
sum+=ht[i].weight*j;
\n平均长度=%g\n"
1.0*sum/m);
voidmain()
{intn=15,i;
char*str[]={"
The"
of"
a"
to"
and"
in"
that"
he"
is"
at"
on"
for"
His"
are"
be"
};
intfnum[]={1192,677,541,518,462,450,242,195,190,181,174,157,138,124,123};
HTNodeht[M];
HCodehcd[N];
{strcpy(ht[i].data,str[i]);
ht[i].weight=fnum[i];
CreateHT(ht,n);
CreateHCode(ht,hcd,n);
DispHCode(ht,hcd,n);
友情提示:
部分文档来自网络整理,供您参考!
文档可复制、编制,期待您的好评与关注!