算法设计实验报告课件Word格式文档下载.docx
《算法设计实验报告课件Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《算法设计实验报告课件Word格式文档下载.docx(25页珍藏版)》请在冰豆网上搜索。
请输入数组长度:
n);
intx;
请输入要查询的数:
x);
n=Binarysearch(a,x,n);
if(n<
0)
无法找到该数!
\n"
else
所查找的值:
%d的位置是:
%d\n"
x,n);
return0;
}
intBinarysearch(inta[],intx,intn)
intleft=0;
intright=n-1;
while(left<
=right)
intmiddle=(left+right)/2;
if(x==a[middle])
returnmiddle;
if(x>
a[middle])
left=middle+1;
else
right=middle-1;
return-1;
二分查找算法复杂性分析:
每执行一次算法的while循环,待搜索数组的大小就减小一半,所以在最坏情况下,while循环被执行了O(logn)次。
循环体内需要O
(1)时间。
所以最坏情况下时间复杂度为O(logn)。
2、在二分查找算法的基础上,实现三分查找算法并对算法的复杂性进行分析。
源程序如下:
#include<
#defineN6
intsearch(intb[N],intx)
intlow=0;
inthigh=N-1;
while(low<
=high)
intm1=(high-low)/3+low;
intm2=high-(high-low)/3;
if(x==b[m1])
returnm1;
elseif(x<
b[m1])
high=m1-1;
elseif(x==b[m2])
returnm2;
elseif(x>
b[m2])
high=m2-1;
else
{
low=m1+1;
high=m2-1;
}
intmain()
{
ints[N];
inty;
请输入序列:
for(inti=0;
scanf("
s[i]);
要查找的数为:
y);
inta;
a=search(s,y);
if(a>
-1)
printf("
位置为:
%d\n"
a);
else
没有找到该数\n"
三分搜索技术时间复杂性分析:
T(n)=O
(1),当n=1时,T(n)=T(
)+O
(1),当n>
1时。
总的来说T(n)=O(
)
3、给定有序序列A={1,2,3,4,5,6},给出分别用二分和三分查找算法查找元素a=4和a=0的过程。
1、二分查找
(1)a=4设置两个变量i,j,排序开始的时候i=0,j=n-1=5;
i=0;
j=5;
(1)假设指针low和high分别为待查元素4所在范围的上界和下界,指针mid=(low+high)/2=3;
(2)先将ST.elem[mid].key与给定值key比较,3<
4,说明待查元素若存在,必在区间[mid+1,high]之间,则令指针low指向mid+1个元素,重新求得mid=(4+6)/2=5
(3)仍将ST.elem[mid].key与给定值key比较,5>
4,说明待查元素若存在,必在区间[mid-1,low]之间,则令指针high指向mid-1个元素,重新求得mid=(4+4)/2=4;
比较ST.elem[mid].key与给定值key,相等,查找成功,所查元素在序列中第三个位置。
2.a=0
i=0;
j=5;
(1)假设指针low和high分别为待查元素0所在范围的上界和下界,指针mid=(low+high)/2=3;
(2)先将ST.elem[mid].key与给定值key比较,3>
0,说明待查元素若存在,必在区间[mid-1,low]
之间,则令指针high指向mid-1个元素,重新求得mid=(1+2)/2=1
(3仍将ST.elem[mid].key与给定值key比较,1>
0,说明待查元素若存在,必在区间[mid-1,low]之间,则令指针high指向mid-1个元素,上界和下界都指向同第一个元素仍没有找到,此时可以得出不存在该元素。
2、三分查找分析过程
A={1,2,3,4,5,6}
查找4left=0m1=1m2=4right=5
A[m1]<
4<
A[m2]left=m1+1right=m2-1=3m1=2m2=3
4=A[m2]已找到位置为m2=3;
查找0left=0m1=1m2=4right=5
0<
A[m1]right=m1-1left=0m1=0m2=0
均不满足判断,所以0不存在
(二)、快速排序问题
1、编程语言不限,实现快速排序算法并对算法的复杂性进行分析。
voidquicksort(inta[],intlow,inthigh)
inti,j,temp;
i=low;
j=high;
temp=a[low];
if(low>
high)
return;
while(i!
=j)
while(a[j]>
=temp&
&
j>
i)
j--;
if(j>
a[i++]=a[j];
while(a[i]<
i++;
a[j--]=a[i];
a[i]=temp;
quicksort(a,low,i-1);
quicksort(a,i+1,high);
voidmain()
inta[N];
请输入数组:
for(intk=0;
k<
6;
k++)
a[k]);
quicksort(a,0,6);
inti;
for(i=0;
%4d"
a[i]);
时间复杂性分析:
最坏情况下T(n)=O(
2、若有序列A={5,2,6,4,1,3},根据快速排序算法的思想,给出升序排序的过程。
排序过程如下:
(1)设置两个变量i,j,排序开始的时候i=0,j=n-1=5;
(2)以第一个数组元素5作为关键数据,赋值给key,即key=A[0]=5;
(3)从j开始向前搜索,由后开始向前搜索j--;
找到第一个小于key的A[j],将A[j]和A[i]互换,即是3和5互换;
(4)从i开始向后搜索,由前向后i++,找到第一个大于key的A[i],将A[i]和A[j]互换;
(5)重复(3)、(4)直到i=j;
开始序列为526413i=0;
j=n-1=5;
关键字为5;
(1)5>
3,将5和3的位置互换;
序列变为326415
(2)2<
5,所以不用交换位置,序列为326415
(3)6>
5,所以将5和6互换位置,序列变为325416
(4)5>
1,所以互换位置,序列变为321456
(5)4<
5,所以不用互换位置,序列仍是321456
(6)再以3为关键字,分别与4,5,6比较,均不用互换位置
(7)3>
1,互换位置后序列变为123456
(8)然后2<
3也不必换位置,i=j比较结束,序列为123456
五、实验心得
算法设计与分析班级13计本实验日期:
2015/11/13
130702010047姓名:
二指导教师:
矩阵连乘问题和0-1背包问题
二、实验目的及要求
1、掌握动态规划的基本思想;
2、采用动态规划思想,编程实现矩阵连乘算法和0-1背包算法;
3、能分析所设计算法的计算复杂性;
(一)、矩阵连乘问题
1、编程语言不限,实现矩阵连乘问题的动态规划算法并对算法的复杂性进行分析。
#defineN30
voidmatrixChain(intp[],intm[N+1][N+1],intb[N+1][N+1])//函数定义;
intn=N;
for(inti=1;
=n;
m[i][i]=0;
intr;
for(r=2;
r<
r++)
{
for(i=1;
=n-r+1;
intj=i+r-1;
m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];
b[i][j]=i;
intk;
for(k=i+1;
j;
intd=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
if(d<
m[i][j])
m[i][j]=d;
b[i][j]=k;
}
}
voidtraceback(inti,intj,intb[][N+1])
if(i==j)
printf("
A%d"
i);
("
traceback(i,b[i][j],b);
traceback(b[i][j]+1,j,b);
)"
main()
inta[2*N];
intc[N+1],flag=1;
intm[N+1][N+1];
intb[N+1][N+1];
请输入矩阵的个数:
scanf("
=2*n-1;
if(i%2==0)
请输入A%d的行:
(i/2)+1);
列:
for(i=1;
=2*n-2;
if(i%2!
=0&
a[i]!
=a[i+1])
flag=0;
break;
intj;
for(j=1;
j<
=n-1;
j++)
c[j]=a[2*j];
if(flag!
=0)
c[0]=a[0];
c[n]=a[2*n-1];
matrixChain(c,m,b);
最优解的结构为:
traceback(1,n,b);
最小数乘次数为%d\n"
m[1][n]);
这%d个矩阵不能连乘!
n);
两个矩阵能够相乘的条件是第一个矩阵的列要等于第二个矩阵的行,如下图所输入的矩阵的值就不能相乘。
算法复杂度分析:
算法matrixChain的主要计算量取决于算法中对r,i和k的3重循环。
循环体的计算量为O
(1),而3重循环的总次数为O(n3)。
因此算法的计算时间上界为O(n3)。
算法所占用的空间显然为O(n2)。
2、若A1的大小为30×
20,A2的大小为20×
5,A3的大小为5×
15,A4的大小为15×
20,A5的大小为20×
20,A1的大小为20×
35,根据矩阵连乘问题的动态规划的算法思想,给出最优计算次序的过程。
计算最优次序过程为:
A1
A2
A3
A4
A5
A6
30×
20
20×
5
5×
15
15×
20
35
根据公式:
m[1][2]=A1A2=30×
20×
5=3000
m[2][3]=A2A3=20×
5×
15=1500
m[3][4]=A3A4=5×
15×
20=1500,
m[4][5]=A4A5=15×
20=6000
m[5][6]=A5A6=20×
35=14000
m[1][3]=A1A2A3=min
=min{5250,10500}=5250
m[2][4]=A2A3A4=min
=min{7500,3500}=3500
m[3][5]=A3A4A5=min
m[4][6]=A4A5A6=min
=min{16500,24500}=16500
=7500
=5500
=7000
=9500
=10500
=15250
最优解为:
(A1A2)(((A3A4)A5)A6)
(二)、0-1背包问题
1、编程语言不限,实现0-1背包问题的动态规划算法并对算法的复杂性进行分析。
intV[15][15];
intmax(intm,intg)//求最大值
if(m>
=g)
returnm;
//m表示物品的重量
elsereturng;
//g表示背包的容量
intKnapSack(intn,intw[],intv[],intx[],intC)
inti,j;
V[i][0]=0;
//表示有物品i,但是背包容量为0
for(j=0;
=C;
V[0][j]=0;
//表示背包有容量,但是没有物品
if(j<
w[i])
V[i][j]=V[i-1][j];
V[i][j]=max(V[i-1][j],V[i-1][j-w[i]]+v[i]);
j=C;
for(i=n-1;
i>
=0;
i--)
if(V[i][j]>
V[i-1][j])
x[i]=1;
//将物品i装入背包的情况
j=j-w[i];
x[i]=0;
//物品i没有被装入背包
选中的物品是:
n;
%d"
x[i]);
returnV[n-1][C];
ints;
intw[15];
intv[15];
intx[15];
intn,i;
intC;
n=5;
请输入背包的最大容量:
C);
输入物品数:
请分别输入物品的重量:
w[i]);
请分别输入物品的价值:
v[i]);
s=KnapSack(n,w,v,x,C);
//函数调用
最大物品价值为:
s);
从m(i,j)的递归式容易看出,算法Knapsack需要O(nc)计算时间;
Traceback需O(n)计算时间;
算法总体需要O(nc)计算时间。
当背包容量c很大时,算法需要的计算时间较多
2、若n=5,c=5,w={2,1,2,2,3},v={2,3,1,3,4},根据0-1背包问题的动态规划算法思想,给出构造最优解的过程。
(1)枚举法:
有5种物品,背包容量c=5
{x1,x2,x3,x4,x5}={0,0,0,0,0},{0,0,0,0,1},{0,0,0,1,0},{0,0,0,1,1},{0,0,1,0,0},{0,0,1,0,1},{0,0,1,1,0},{0,1,0,0,0},{0,1,0,0,1},{0,1,0,1,0},{0,1,0,0,0},{0,1,1,0,0},{0,1,0,0,0},{0,1,1,1,0},{1,1,0,1,0}
{x1,x2,x3,x4,x5}={1,1,0,1,0}
v1*x1+v2*x2+v3*x3+v4*x4+v5*x5=8
(2)构造最优解
4
3
2
1
m[1][5]>
m[2][5]物品1被选x[1]=1c=5-w[1]=3
m[2][3]>
m[3][3]物品2被选x[2]=1c=3-w[2]=2
m[3][2]=m[4][2]物品3未被选x[3]=0
m[4][2]>
m[5][2]物品4被选x[4]=1c=2-w[2]=0
m[5][2]=0物品5未被选x[5]=0
X1
X2
X3
x4
X5
算法设计与分析班级:
13计本实验日期:
2015/12/5
130702010047姓名陈美指导教师:
贪心算法——最优装载问题
1、掌握贪心算法的基本思想;
2、利用贪心算法思想,编程实现最优装载问题;
1、编程语言不限,实现教材P95页的货船最优装载算法并对该算法的复杂性进行分析。
程序源代码如下:
voidSort(int*w,int*t,intn)
inti,j,count=0;
int*s=newint[n+1];
for(i=1;
i++)
s[i]=w[i];
t[i]=0;
count=0;
for(j=0;
if(i!
if(s[i]>
s[j])
count++;
while(t[count]!
count++;
t[count]=i;
}
voidloading(intw[],intx[],intc,intn)
int*t=newint[n+1];
Sort(w,t,n);
//排序
for(inti=1;
x[i]=0;
for(intj=1;
=n&
w[t[j]]<
=c;
x[t[j]]=1;
c=c-w[t[j]];
intX[20],W[20],n,c;
请输入船只载重:
c);
请输入集装箱数量:
输入物品的重量序列:
for(inti=1;
W[i]);
loading(W,X,c,n);
最优装载为"
for(intj=1;
%d"
X[j]);
实验截图如下:
时间复杂度分析:
算法的主要计算量在于将集装箱依其重量从小到大排序,程序中有两个嵌套for循环,所以复杂性为:
O(n*n)。
2、假设某公司现有8个集装箱急需搬上一艘大货船,它们的重量分别是[W0,W2,…,W7]=[100,200,50,90,150,50,20,80],船只载重C=400。
求该条件下的最优装载问题。
(要求给出具体的过程)
解答过程如下:
从剩下的集装箱中,选择重量最小的集装箱。
这种选择次序可以保证所选的集装箱总重量最小,从而可以装载更多的集装箱。
根据这种贪心策略,首先选择最轻的集装箱,然后选择次轻的,如此下去直到所有集装箱均装上船或船上不能容纳其他集箱。
n=8,[W1,W2,…,W8]=[100,200,50,90,150,50,20,80],c=400。
利用贪心算法时,所考察集装箱的顺序为7,3,6,8,4,1,5,2。
集装箱7,3,6,8,4,1的总重量为390个单位且已被装载,剩下的装载能力为10