算法设计分析.docx

上传人:b****3 文档编号:13275620 上传时间:2023-06-12 格式:DOCX 页数:20 大小:22.74KB
下载 相关 举报
算法设计分析.docx_第1页
第1页 / 共20页
算法设计分析.docx_第2页
第2页 / 共20页
算法设计分析.docx_第3页
第3页 / 共20页
算法设计分析.docx_第4页
第4页 / 共20页
算法设计分析.docx_第5页
第5页 / 共20页
算法设计分析.docx_第6页
第6页 / 共20页
算法设计分析.docx_第7页
第7页 / 共20页
算法设计分析.docx_第8页
第8页 / 共20页
算法设计分析.docx_第9页
第9页 / 共20页
算法设计分析.docx_第10页
第10页 / 共20页
算法设计分析.docx_第11页
第11页 / 共20页
算法设计分析.docx_第12页
第12页 / 共20页
算法设计分析.docx_第13页
第13页 / 共20页
算法设计分析.docx_第14页
第14页 / 共20页
算法设计分析.docx_第15页
第15页 / 共20页
算法设计分析.docx_第16页
第16页 / 共20页
算法设计分析.docx_第17页
第17页 / 共20页
算法设计分析.docx_第18页
第18页 / 共20页
算法设计分析.docx_第19页
第19页 / 共20页
算法设计分析.docx_第20页
第20页 / 共20页
亲,该文档总共20页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

算法设计分析.docx

《算法设计分析.docx》由会员分享,可在线阅读,更多相关《算法设计分析.docx(20页珍藏版)》请在冰点文库上搜索。

算法设计分析.docx

算法设计分析

武汉科技大学城市学院

算法分析与设计》

上机实验报告

课程名称

数据结构课程设计信息工程学部

软件工程

软件三班

洪汉山

201510159320

指导教师

林晓丽

副教授

2017年11月15日

实验1分治法

(一)2

1.1实验目的2

1.2实验内容及要求2

1.3算法设计思路及步骤2

1.4程序代码3

1.5运行结果截图7

实验2分治法

(二)_分金块8

2.1实验目的8

2.2实验内容及要求8

2.3算法设计思路及步骤8

2.4程序代码9

2.5运行结果截图11

实验三动态规划_数字三角形11

3.1实验目的11

3.2实验内容及要求11

3.3算法设计思路及步骤12

3.4程序代码12

3.5运行结果截图14

实验四购物券问题15

4.1实验目的15

4.2实验内容及要求15

4.3算法设计思路及步骤15

4.4程序代码16

4.5运行结果截图17

总结18

实验1分治法

(一)

1.1实验目的

1)掌握分治法的基本思想和求解步骤。

2)理解分治法的精髓,即如何分?

如何治?

才能使得算法效率更高。

3)通过实例编程,掌握运用分治法来解决实际问题的方法。

1.2实验内容及要求

问题一:

二分查找

给定已排好序的n个元素s1,⋯,sn,现要在这n个元素中找出一特定元素x要求采用分治法求解,即将问题分解为若干个规模较小、相互独立、与原问题形式相同的子问题;采用递归和非递归两种方式实现。

问题二:

合并排序

设待排序列A={8,3,2,9,7,1,5,4},采用合并排序算法对序列进行排序。

问题三:

快速排序

理解快速排序的思想,实现快速排序。

样例如:

49,38,65,97,76,13,27。

1.3算法设计思路及步骤

二分查找:

分为二分递归和二分非递归二分非递归算法思路:

要用到循环,在循环中开始标记和结束标记不断改变,循环的判断条件就是开始标记是否在结束标记之前。

若查找成功则返回中间元素标记,若查找失败则返回-1。

所以非递归算法需要三个参数:

数组起始地址、数组长度以及要查找的数字。

二分递归算法思路:

判断条件是一样的,在调用自身的过程中,要改变的参数要么是开始标记,要么是结束标记。

所以对于递归算法,需要四个参数:

数组起止地址、要查找的数字、开始标记与结束标记。

合并排序算法思路:

原理,把原始数组分成若干子数组,对每一个子数组进行排序,继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组。

快速排序算法思路:

快速排序是找出一个元素(理论上可以随便找一个)作为基准(pivot),然后对数组进行分区操作,使基准左边元素的值都不大于基准值,基准右边的元素值都不小于基准值,如此作为基准的元素调整到排序后的正确位置。

递归快速排序,将其他n-1个元素也调整到排序后的正确位置。

最后每个元素都是在排序后的正确位置,排序完成。

1.4程序代码

//非递归实现

intbinarySearch1(int*s,intlow,inthigh,intx){

intmid=0;

while(low<=high)

{

mid=(low+high)/2;

if(x==s[mid])

{

returnmid;

}

elseif(x>s[mid])

{

low=mid+1;

}

else

{

high=mid-1;

}

}return-1;

//递归实现

intbinarySearch2(int*s,intlow,inthigh,intx)

{

intmid=(low+high)/2;

intindex=0;//设置一个指针

if(low<=high)

{

if(x==s[mid])

{returnmid;

}elseif(x>s[mid])

{index=binarySearch2(s,mid+1,high,x);

}

else

{

index=binarySearch2(s,low,mid-1,x);

}

}

else

return-1;

returnindex;

}

intmain()

{

ints[]={1,3,5,7,12,15,17,19,24};

intlen=sizeof(s)/sizeof(int);//计算数组s中有多少个元素、长度

为多少

intx=19;

intindex=binarySearch2(s,0,len-1,x);

if(index==-1)

printf("查找的数x=%d,这个数在已知数组的元素中不存在。

\n",x,index);

else

printf("查找的数x=%d,这个数在已知数组的元素中下标为%d。

\n",x,index);

}

合并排序:

#include

#defineN10

//用递归实现归并排序

voidmerge(intX[],intlow,intmid,inthigh){

inta[N];//定义一个临时缓冲区

inti=low,j=mid+1,k=low;//k是a的下标,i、j分别为a[low...mid]和a[mid+1...high]的下标

for(;i<=mid&&j<=high;k++)//依次比较两个子序列中数据元素的

大小

{

if(X[i]<=X[j])//

a[k]=X[i++];//else

a[k]=X[j++];//}while(i<=mid)//a[k++]=X[i++];while(j<=high)//a[k++]=X[j++];

将较小的数移入缓冲区

将a[low...m]中的记录放入a中

将a[m+1...high]中的记录放入a中

将a[low...m]余下部分复制到a

将a[m+1...high]余下部分复制到a

 

for(k=low;k<=high;k++)//

X[k]=a[k];

}

voidMergeSort(intX[],intlow,inthigh)//{

intmid;

if(low

{

mid=(low+high)/2;

MergeSort(X,low,mid);//MergeSort(X,mid+1,high);//序列

merge(X,low,mid,high);//行归并

}

}

intmain(void)

{

inti;

intX[N]={8,3,2,9,7,1,5,4};

MergeSort(X,0,7);

for(i=0;i<8;i++)

printf("%d",X[i]);

printf("\n");

将缓冲区中的数据元素复制回原序列中

用递归方式定义归并排序函数

将子序列X[low~mid]归并为有序序列将子序列X[mid+1~high]归并为有序

将子序列X[low~mid]和x[mid+1~high]进

}

快速排序:

#include

voidquiksort(inta[],intlow,inthigh)

{

inti=low;

intj=high;

inttemp=a[i];

if(low

{

while(i

{

while((a[j]>=temp)&&(i

{

j--;

}

a[i]=a[j];

while((a[i]<=temp)&&(i

i++;

}

a[j]=a[i];

}

a[i]=temp;

quiksort(a,low,i-1);quiksort(a,j+1,high);

}

else

{

return;

}

}

voidmain()

{

intarry[]={49,38,65,97,76,13,27};

quiksort(arry,0,15);

for(inti=0;i<15;i++)

{

printf("%d",arry[i]);

}

printf("\n");

}

1.5运行结果截图

实验2分治法

(二)_分金块

2.1实验目的

1.掌握分治法的基本思想和求解步骤。

2.理解分治法的精髓,即如何分?

如何治?

才能使得算法效率更高。

3.通过实例编程,掌握运用分治法来解决实际问题的方法。

2.2实验内容及要求

问题描述:

老板有一袋金块(共n块),最优秀的雇员得到其中最重的一块,最差的雇员得到其中最轻的一块,假设有一台比较重量的仪器,我们希望用最少的比较次数找出最重、最轻的金块。

要求:

必须用分治法(二分法)解决上述问题,禁止用排序法和蛮力法。

2.3算法设计思路及步骤

算法思路:

假设袋中有n块金。

当n很小时,如n=2时,要找出最重的金块,一次就够了。

当n比较大时(n>2),首先,把这袋金块分成两个小袋A和B,然后分别找出A和B中最重和最轻的金块,最后比较A中和B中最重和最轻的,这样就可以找到最重和最轻的金块。

2.4程序代码

#include

#include#includeusingnamespacestd;

floatmax(floatg1,floatg2)//比较找大值

return(g1>g2?

g1:

g2);

}

floatmin(floatg1,floatg2)//比较找小值

{return(g1

g1:

g2);

}

floatSearch_Max(floatg[],intleft,intright)//用二分法递归找最大值

{

if(left==right)//当只有一个数时,直接返回该值

{

floatmax;

max=g[right];

returnmax;

}

if(right-left==1)

{

floatLM,RM;

LM=g[left];

RM=g[right];

return(max(LM,RM));

}

if(right-left>1)

{

floatLM,RM;

intmid=(left+right)/2;//取中点

LM=Search_Max(g,left,mid);

RM=Search_Max(g,mid,right);//左半部分,右半部分的最大值比较找最大

return(max(LM,RM));

}

}

floatSearch_Min(floatg[],intleft,intright)//用二分法递归找最小值

{

if(left==right)

{

floatmin;

min=g[right];

returnmin;

}

if(right-left==1)

{

floatLM,RM;

LM=g[left];

RM=g[right];return(min(LM,RM));

}

if(right-left>1)

{

floatLM,RM;

intmid=(left+right)/2;

LM=Search_Min(g,left,mid);

RM=Search_Min(g,mid,right);//左半部分,右半部分的最小值比较找最小return(min(LM,RM));

}

}

intmain()

{

floatgold[100];

intn;

cout<<"请输入金块的数目:

";

cin>>n;

cout<<"请输入各金块的重量:

";

for(inti=0;i

{

cin>>gold[i];

}

cout<<"最重的金块:

"<

cout<<"最轻的金块:

"<

return0;

}

2.5运行结果截图

实验三动态规划_数字三角形

3.1实验目的

1.掌握动态规划的基本思想和基本步骤。

2.理解动态规划的精髓,如何才能提高算法的效率。

3.比较动态规划与贪心法的区别,并思考最小硬币问题是否能用贪心法求解。

4.通过实例编程,掌握运用动态规划来解决实际问题的过程。

3.2实验内容及要求

动态规划思想实现编程:

给一个数字三角形,找出从第一层到最后一层的一条路,使得所经过的权值之和最大。

输入样例:

5

7

38

810

2744

45265

输入的第一行是一个整数N(1

下面的N行给出数字三角形。

数字三角形上的数的范围都在0和100之间。

输出要求:

输出最大的和。

1、用递归函数实现。

2、用递推方法实现。

3.3算法设计思路及步骤

算法思路:

用二维数组存放数字三角形

D(r,j):

第r行第j个数字(r,j从1开始算)

MaxSum(r,j):

从D(r,j)到底边的各条路径中,最佳路径的数字之和。

3.4程序代码

递归:

#include

#include

#defineMAX_NUM100

intD[MAX_NUM+10][MAX_NUM+10];

intN;

intaMaxSum[MAX_NUM+10][MAX_NUM+10];

intMaxSum(intr,intj)

{

if(r==N)

returnD[r][j];

if(aMaxSum[r+1][j]==-1)aMaxSum[r+1][j]=MaxSum(r+1,j);

if(aMaxSum[r+1][j+1]==-1)aMaxSum[r+1][j+1]=MaxSum(r+1,j+1);

if(aMaxSum[r+1][j]>aMaxSum[r+1][j+1])

returnaMaxSum[r+1][j]+D[r][j];

returnaMaxSum[r+1][j+1]+D[r][j];

}

intmain()

{

intm;

scanf("%d",&N);

memset(aMaxSum,-1,sizeof(aMaxSum));//将aMaxSum全部置成-1,表示开始所有的MaxSum(r,j)都没有算过

for(inti=0;i<=N;i++)

{

for(intj=1;j<=i;j++)

{scanf("%d",&D[i][j]);

}

}

printf("%d",MaxSum(1,1));return0;

}

递推:

#include

#include

#defineMAX_NUM100

intD[MAX_NUM+10][MAX_NUM+10];intN;

intaMaxSum[MAX_NUM+10][MAX_NUM+10];

voidmain()

{

inti,j;scanf("%d",&N);

for(i=1;i<=N;i++)

for(j=1;j<=i;j++)scanf("%d",&D[i][j]);

for(j=1;j<=N;j++)aMaxSum[N][j]=D[N][j];

for(i=N;i>1;i--)

for(j=1;j

{

if(aMaxSum[i][j]>aMaxSum[i][j+1])aMaxSum[i-1][j]=aMaxSum[i][j]+D[i-1][j];else

aMaxSum[i-1][j]=aMaxSum[i][j+1]+D[i-1][j];}

printf("%d\n",aMaxSum[1][1]);

}

3.5运行结果截图

实验四购物券问题

4.1实验目的

4.选择合适的算法策略解决问题。

5.理解不同方法的精髓,如何才能提高算法的效率。

6.比较动态规划、贪心法、回溯法的区别

7.通过实例编程,掌握解决实际问题的过程。

4.2实验内容及要求

公司发了某商店的购物券1000元,限定只能购买店中的m种商品每种商品的价格分别为m1,m2,⋯,要求程序列出所有的正好能消费完该购物券的不同购物方法。

程序输入:

第一行是一个整数m,代表可购买的商品的种类数。

接下来是m个整数,每个1行,分别代表这m种商品的单价。

程序输出:

第一行是一个整数,表示共有多少种方案第二行开始,每种方案占1行,表示对每种商品购买的数量,中间用空格分隔。

4.3算法设计思路及步骤

算法思路:

解这道题目受到21位花朵数的启发,可以给每件商品设置一个数量标志num[],价格prize[],先输入价格,并从所有商品中找到最便宜的那个min,然后max=1000/min,这个max就是每个商品购买的最大数量,接下来我们对每个商品购买的数量进行枚举,通过递归实现,当枚举到第m+1位的时候,递归停止,算一下此时所购买的商品的价格,如果等于1000,就把计数器count加1,并把num[]数组中的数据全部保存下来,当递归全部结束,就可以输出count的值以及保存的num[]值。

4.4程序代码

#include#includeintm;//物品数intp[100];//价格

intans[100][100];//ans[i][j]表示第i个方案中第j个物品被选数

intnum[100];//num[i]表示第i件物品被选的个数

intcas=0;//方案数

intmoney=0;//花的钱

voidbuy(intn)//n表示当前搜索到的物品编号

{

if(money>1000||n>=m)//当花的钱超过预算或者所有的物品都已遍历过了,不再继续搜索下去

return;

if(money==1000)//当花的钱正好为1000,满足要求

{

for(inti=0;i

cas++;

return;

}num[n]++;//选该物品money+=p[n];

buy(n);//可以继续选该物品num[n]--;//不选该物品,前面加的要减去

money-=p[n];//钱也相应的减buy(n+1);//选下一个物品

}

intmain()

{

inti;scanf("%d",&m);for(i=0;i

memset(num,0,sizeof(num));//将以num为起始地址的数组全部初始化为0

buy(0);printf("%d\n",cas);for(i=0;i

for(intj=0;j

printf("\n");

}return0;

}

4.5运行结果截图

总结

通过这几次的实验和学习,我更加清楚的知道它们的运行机理,比如分治法解题的一般步骤:

(1)分解,将要解决的问题划分成若干规模较小的同类问题;

(2)求解,当子问题划分得足够小时,用较简单的方法解决;(3)合并,按原

问题的要求,将子问题的解逐层合并构成原问题的解。

做实验重在动手动脑,还是要多写写实验,才是硬道理。

排序的话首先要掌握基本的排序思想,然后把逻辑语言转化成程序语言,参考网上的各种答案优化自己的算法程序结合所学知识。

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。

与分治法不同的是,适合于用动态规划求解的问题,经分解得到子问题往往不是互相独立的。

若用分治法来解这类问题,则分解得到的子问题数目太多,有些子问题被重复计算了很多次。

贪心算法的思路和步骤是:

建立数学模型来描述问题;把求解的问题分成若干个子问题;对每一子问题求解,得到子问题的局部最优解;把子问题的解局部最优解合成原来解问题的一个解。

感谢在这几次实验中老师和同学给予的帮助,我会在今后的学习和生活中更加努力上进。

实验报告评分表

评分标准:

1.学生是否严格遵守上机纪律,按照规定时间完成实验任务(占30%)

2.算法设计的质量与规范:

(占40%)

(1)完成题目的数量

(2)是否采用了良好的设计方法,独立完成上机编程

(3)算法设计思路是否清晰,时间复杂度是否合理

(4)程序是否运行正常

3.实验上机报告书的质量与规范(占30%)

教师评分:

1.学生出勤得分:

A)优

B)

C)中

D)及格

E)不及格

2算法设计得分:

A)优

B)

C)中

D)及格

E)不及格

3.实验报

告得分:

A)优

B)

C)中

D)及格

E)不及格

总分:

教师评语:

根据该生在实验上机期间,是否严格遵守上机纪律,按照规定时间完成

设计任务,完成的算法设计的质量与规范,提交的实验上机报告书的质量与规范等多方面的评分,该生本学期实验上机的评分为:

教师签名:

日期:

年月日

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2