算法设计与分析案例Word文档格式.docx
《算法设计与分析案例Word文档格式.docx》由会员分享,可在线阅读,更多相关《算法设计与分析案例Word文档格式.docx(19页珍藏版)》请在冰点文库上搜索。
cout<
<
list[i];
endl;
else
for(inti=k;
swap(list[k],list[i]);
perm(list,k+1,m);
voidmain()
intlist[3]={1,2,3};
perm(list,0,2);
2、voidhanoi(intn,inta,intb,intc)
if(n>
0)
hanoi(n-1,a,c,b);
move(a,b);
hanoi(n-1,c,b,a);
实验二分治算法(4学时)
1、熟悉二分搜索算法和快速排序算法;
2、初步掌握分治算法;
二、实验题
1、设a[0:
n-1]是一个已排好序的数组。
请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。
当搜索元素在数组中时,I和j相同,均为x在数组中的位置。
设有n个不同的整数排好序后存放于t[0:
n-1]中,若存在一个下标i,0≤i<n,使得t[i]=i,设计一个有效的算法找到这个下标。
要求算法在最坏的情况下的计算时间为O(logn)。
2、在快速排序中,记录的比较和交换是从两端向中间进行的,关键字较大的记录一次就能交换到后面单元,关键字较小的记录一次就能交换到前面单元,记录每次移动的距离较大,因而总的比较和移动次数较少。
三、实验提示
1、用I,j做参数,且采用传递引用或指针的形式带回值。
boolBinarySearch(inta[],intn,intx,int&
i,int&
j)
{
intleft=0;
intright=n-1;
while(left<
right)
intmid=(left+right)/2;
if(x==a[mid])
i=j=mid;
returntrue;
if(x>
a[mid])
left=mid+1;
right=mid-1;
i=right;
j=left;
returnfalse;
}
intSearchTag(inta[],intn,intx)
if(x==a[mid])returnmid;
return-1;
2、
template<
classType>
voidQuickSort(Typea[],intp,intr)
if(p<
r){
intq=Partition(a,p,r);
QuickSort(a,p,q-1);
//对左半段排序
QuickSort(a,q+1,r);
//对右半段排序
intPartition(Typea[],intp,intr)
inti=p,j=r+1;
Typex=a[p];
//将<
x的元素交换到左边区域
//将>
x的元素交换到右边区域
while(true){
while(a[++i]<
x);
while(a[--j]>
if(i>
=j)break;
Swap(a[i],a[j]);
a[p]=a[j];
a[j]=x;
returnj;
实验三归并排序的分治策略设计(4学时)
[实验目的]
1.熟悉二分检索问题的线性结构表示和二分检索树表示;
2.熟悉不同存储表示下求解二分检索问题的递归算法设计;
3.通过实例转换,掌握将递归算法转换成迭代算法的方法;
4.掌握应用递归或迭代程序设计实现分治法求解问题的抽象控制策略.
[预习要求]
1.认真阅读算法设计教材和数据结构教材内容,熟悉不同存储表示下求解二分检索问题的原理或方法;
2.针对线性结构表示和二分检索树表示设计递归算法;
3.参考教材和课堂教学内容,根据将递归算法转换成迭代算法的一般步骤将二分检索递归算法转换成相应的迭代算法.
[算法或程序设计参考]
线性结构
intdata[10]={/*10个互异的、无序的原始整数*/};
typedefstruct{ints[100];
inttop;
}STACK;
intPartition(int*data,intlow,inthigh)
功能:
将data[low,high]进行快速分类划分,返回枢轴记录关键字的位置索引.
intQSort1(int*data,intlow,inthigh)
将data[low,high]进行快速分类的递归算法.
intQSort2(int*data,intlow,inthigh)
将data[low,high]进行快速分类的迭代算法.
intBSearch1(int*data,intkey)
在data数组中检索key的二分检索递归算法,成功时返回位置索引,否则返回-1.
intBSearch2(int*data,intkey)
在data数组中检索key的二分检索迭代算法,成功时返回位置索引,否则返回-1.
树结构
typedefstructNODE{intkey;
structNODE*lch,*rch;
}TNODE,*BT;
typedefstructParameters{BT*t;
intkey;
BTf;
BT*p}PARA;
typedefstruct{PARAs[100];
intInsertBT(BT*t,intkey)
功能:
在二分检索树t中插入关键字为key的元素,成功时返回1,否则返回0.
intTSearch1(BT*t,intkey,BTf,BT*p)
用递归算法在二分检索树t中查找关键字为key的元素,成功时返回1,p指向该元素节点,否则p指向查找路径上最后一个节点并返回0,f指向t的双亲,其初始调用值为NULL.
intTSearch2(BT*t,intkey,BTf,BT*p)
用迭代算法在二分检索树t中查找关键字为key的元素,成功时返回1,p指向该元素节点,否则p指向查找路径上最后一个节点并返回0,f指向t的双亲,其初始调用值为NULL.
[实验步骤]
1.调试线性结构表示下的快速分类与二分检索递归程序,直至正确为止;
2.调试线性结构表示下的快速分类与二分检索迭代程序,直至正确为止;
3.待各功能子程序调试完毕,去掉测试程序,将程序整理成功能模块存盘备用.
[实验报告要求]
1.阐述实验目的和实验内容;
2.提交实验程序的功能模块;
3.阐述将递归算法改写成迭代算法的一般方法;
4.用类C语言阐述分治法递归与迭代实现抽象控制策略.
[思考与练习]
1.怎样优化由递归程序改写的迭代程序?
2.设计二分检索树的构造与检索递归程序,并将其改写成相应的迭代算法。
实验四哈夫曼编码的贪心算法设计(4学时)
1.根据算法设计需要,掌握哈夫曼编码的二叉树结构表示方法;
2.编程实现哈夫曼编译码器;
3.掌握贪心算法的一般设计方法。
1.认真阅读数据结构教材和算法设计教材内容,熟悉哈夫曼编码的原理;
2.设计和编制哈夫曼编译码器。
[参考数据类型或变量]
typedefElemTypechar;
typedefstructnode{
intw;
intflag;
ElemTypec;
structnode*plink,*llink,*rlink;
charcode[m];
}Node;
Node*num[n],*root;
[参考子程序接口与功能描述]
voidSetTree(NODE*root)
从终端读入字符集大小n,以及n个字符和n个权值,建立哈夫曼树
voidEnCode(Node*p)
利用已建好的哈夫曼树,对输入的正文进行编码
voidDeCode(void)
利用已建好的哈夫曼树,将输入的代码进行译码
1.设计SetTree的测试方案和程序,输入测试数据,修改并调试程序,直至正确为止;
2.设计EnCode的测试方案和程序,输入测试数据,修改并调试程序,直至正确为止;
3.设计DeCode的测试方案和程序,输入测试数据,修改并调试程序,直至正确为止;
4.将你的程序整理成功能模块存盘备用。
3.记录最终测试数据和测试结果。
[思考题]
1.试证明哈夫曼问题具有贪心选择性质;
试证明哈夫曼问题具有最优子结构性质。
实验五Kruskal算法的设计(4学时)
1.根据算法设计需要,掌握连通网的灵活表示方法;
2.掌握最小生成树的Kruskal算法;
3.基本掌握贪心算法的一般设计方法;
4.进一步掌握集合的表示与操作算法的应用.
1.认真阅读算法设计教材和数据结构教材内容,熟习连通网的不同表示方法和最小生成树算法;
2.设计Kruskal算法实验程序.
typedefNodeNumberint;
/*节点编号*/
typedefCostTypeint;
/*成本值类型*/
typedefElemTypeNodeNumber/*实型或任意其它元素类型*/
typedefstruct{intElemType;
inttag;
}NODE;
typedefstruct{CostTypecost;
NodeNumbernode1,node2;
}EDGE;
NODEset[]={{1,-1},…,{n,-1}};
/*节点集,n为连通网的节点数*/
EDGEes[]={{valuesofe1},…,{valuesofem}};
/*边集,m为连通网的边数*/
EDGEst[n-1];
/*最小生成树的边集*/
intFind(NODE*set,ElemTypeelem)
在数组set中顺序查找元素elem,如果不成功,返回-1;
否则,使用带压缩规则的查找算法,返回所在子集的根节点索引.
intUnion(NODE*set,ElemTypeelem1,ElemTypeelem2)
应用Find算法首先找到elem1和elem2所在的子集,然后应用带加权规则的并运算算法合并两个子集.不成功时,返回-1;
否则,返回并集的根节点索引.
voidSort(EDGE*es,intn)
用任意分类算法将连通图的边集按成本值的非降次序分类.
voidKruskal(EDGE*es,intm,NODE*set,intn,EDGE*st)
对有n个节点,m条边的连通网,应用Kruskal算法生成最小生成树,最小生成树的边存储在数组st中.
voidOutput(EDGE*st,intn)
输出最小生成树的各条边.
1.设计测试问题,修改并调试程序,输出最小生成树的各条边,直至正确为止;
2.待各功能子程序调试完毕,去掉测试程序,将你的程序整理成功能模块存盘备用.
2.阐述Kruskal算法的原理方法;
3.提交实验程序的功能模块;
4.提供测试数据和相应的最小生成树.
1.设计由连通网初始边集数组生成最小堆的算法;
2.设计输出堆顶元素,并将剩余元素调整成最小堆的算法;
3.针对连通网初始边集最小堆表示,设计Kruskal算法;
4.采用成本邻接矩阵表示连通网时,在剩余边中如何实现最小成本边的查找?
采用成本邻接矩阵表示连通网时,用C语言实现Prim算法.
实验六动态规划算法(4学时)
1、熟悉最长公共子序列问题的算法;
2、初步掌握动态规划算法;
若给定序列X={x1,x2,…,xm},则另一序列Z={z1,z2,…,zk},是X的子序列是指存在一个严格递增下标序列{i1,i2,…,ik}使得对于所有j=1,2,…,k有:
zj=xij。
例如,序列Z={B,C,D,B}是序列X={A,B,C,B,D,A,B}的子序列,相应的递增下标序列为{2,3,5,7}。
给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
给定2个序列X={x1,x2,…,xm}和Y={y1,y2,…,yn},找出X和Y的最长公共子序列。
include"
stdlib.h"
#include"
string.h"
voidLCSLength(char*x,char*y,intm,intn,int**c,int**b)
inti,j;
for(i=1;
i<
=m;
i++)c[i][0]=0;
=n;
i++)c[0][i]=0;
i++)
for(j=1;
j<
j++)
if(x[i]==y[j])
c[i][j]=c[i-1][j-1]+1;
b[i][j]=1;
elseif(c[i-1][j]>
=c[i][j-1])
c[i][j]=c[i-1][j];
b[i][j]=2;
else
{
c[i][j]=c[i][j-1];
b[i][j]=3;
voidLCS(inti,intj,char*x,int**b)
if(i==0||j==0)return;
if(b[i][j]==1)
LCS(i-1,j-1,x,b);
printf("
%c"
x[i]);
elseif(b[i][j]==2)
LCS(i-1,j,x,b);
elseLCS(i,j-1,x,b);
实验七动态规划算法(4学时)
1、熟悉最长最大字段和问题的算法;
2、进一步掌握动态规划算法;
若给定n个整数组成的序列a1,a2,a3,……an,求该序列形如ai+ai+1+……+an的最大值。
intMaxSum(intn,int*a,int&
besti,int&
bestj)
intsum=0;
for(inti=1;
=n;
for(intj=i;
j<
j++)
intthissum=0;
for(intK=i;
k<
=j;
k++)thissum+=a[k];
if(thissum>
sum)
sum=thissum;
besti=i;
bestj=j;
returnsum;
for(intj=i;
thissum+=a[j];
}
实验八
回溯算法(4学时)
1、掌握装载问题的回溯算法;
2、初步掌握回溯算法;
有一批共n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且装载问题要求确定是否有一个合理的装载方案可将这个集装箱装上这2艘轮船。
如果有,找出一种装载方案。
voidbacktrack(inti)
{//搜索第i层结点
n)//到达叶结点
更新最优解bestx,bestw;
return;
r-=w[i];
if(cw+w[i]<
=c){//搜索左子树
x[i]=1;
cw+=w[i];
backtrack(i+1);
cw-=w[i];
if(cw+r>
bestw){
x[i]=0;
//搜索右子树
r+=w[i];
实验(设计)报告参考格式
多段图问题的动态规划算法与实现
一、设计目的
1.掌握有向网的成本邻接矩阵表示法;
2.掌握多段图问题的动态规划递推算法;
3.进一步掌握动态规划法的基本思想和算法设计方法;
……
二、设计内容
1.任务描述
1)多段图问题简介
2)设计任务简介
设计求解多段图问题的动态规划算法,即设计和实现多段图问题的表示方案、动态规划递推算法,设计对算法或程序的测试方案并完成测试。
2.多段图问题的表示方案
本设计采用成本邻接矩阵表示多段图,针对多段图(可插入图例)描述成本邻接矩阵的规模与元素意义……
3.递推过程的抽象描述
本设计采用前向或后向递推公式。
用自然语言、伪程序设计语言或流程图等形式针对多段图问题的求解(抽象地)描述递推过程……
4.主要数据类型与变量
typedefCostTypeint;
CostTypecost[n][n]={…};
/*成本邻接矩阵,n为顶点数*/
NodeNumberpath[k];
/*k段图最短路径上的节点编号数组*/
NodeNumbercur=-1;
/*当前邻接节点*/
(必要时,可对数据类型和变量进一步解释或说明,增加可读性)
5.算法或程序模块
intFindForward(CostType*cost[n],NodeNumberi,NodeNumbercur)
根据邻接矩阵查找节点i的下一个前向邻接节点,成功时返回节点编号,否则返回-1;
cur为当前的前向邻接节点,第一次调用时其值为-1.
intFindBackward(CostType*cost[n],NodeNumberi,NodeNumbercur)
根据邻接矩阵查找节点i的下一个后向邻接节点,成功时返回节点编号,否则返回-1;
cur为当前的后向邻接节点,第一次调用时其值为-1.
(必要时,可对算法或程序模块进一步解释或说明,增加可读性)
三、测试
1.方案
描述测试方案、测试模块、测试数据实例(文字数据、图或表等形式)……
2.结果
结合测试数据实例描述测试过程和测试结果,最好给出表示测试过程和结果的抓图,对测试结果进行分析并得出结论。
四、总结与讨论
可针对本设计谈体