递归算法的应用.docx
《递归算法的应用.docx》由会员分享,可在线阅读,更多相关《递归算法的应用.docx(15页珍藏版)》请在冰豆网上搜索。
递归算法的应用
摘要
递归做为一种算法在程序设计语言中广泛应用。
是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。
递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写程序能使程序变得简洁和清晰。
递归的主要优点在于:
某些类型的算法采用递归比采用迭代算法要更加清晰和简单。
例如快速排序算法按照迭代方法是很难实现的。
还有其他一些问题,特别是人工智能问题,就依赖于递归提供解决方案。
最后,有些人认为递归要比迭代简单递归算法是一种直接或者间接地调用自身的算法。
在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。
递归算法解决问题的特点:
(1)递归就是在过程或函数里调用自身。
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
(3)递归算法解题通常显得很简洁,但递归算法解题的运行效率较低。
所以一般不提倡用递归算法设计程序。
(4)在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。
递归次数过多容易造成栈溢出等。
所以一般不提倡用递归算法设计程序。
。
关键字:
递归,程序设计,算法
目录
1.绪论1
1.1问题的提出1
1.2任务与分析1
2.0-1背包2
2.1算法2
2.2程序2
3.Hanoi塔4
3.1算法4
3.2程序4
4.棋子移动5
4.1算法5
4.2程序6
5.全排列8
5.1算法8
5.2程序9
6.约瑟夫10
6.1算法10
6.2程序11
结论13
参考文献14
绪论
1.1问题的提出
一个过程或函数直接或间接地调用自己本身称为递归,现在我们以具体例题来分析讲解递归问题。
递归的一般思路:
把原问题分解为更小的子问题,再从子问题里慢慢寻找原问题的解。
解题时首先列出递归表达式,然后用程序语言的方式把他表现出来。
往往递归都可转化为循环或者模拟调用栈来实现,但是递归表达更利于理解。
1.1.1递归应用
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。
(Fibonacci函数)
(2)问题解法按递归算法实现。
(回溯)
(3)数据的结构形式是按递归定义的。
(树的遍历,图的搜索)
1.1.2递归的缺点:
递归算法解题的运行效率较低,在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。
递归次数过多容易造成栈溢出等。
1.2任务与分析
(1)0\1背包问题的递归算法和程序;
(2)n阶hanoi塔的递归算法和程序;
(3)棋子移动的递归算法和程序;
(4)n个元素全排列的递归算法和程序;
(5)约瑟夫问题的递归算法和程序;
(6)总结可用递归算法实现的问题。
0-1背包
2.1算法
find(i,tw,tv)
//判定是否放入该物品
//输入:
当前物品编号i,当前背包重量tw和物品总价值tv
//输出:
问题解opt[1..n1]
iftw+w[i]<=limitW
cop[i]←1
ififind(i+1,tw+w[i],tv)
else
fork=0ton1do
opt[k]←cop[k]
maxV←tv
cop[i]←0
iftv-v[i]>maxV
ififind(i+1,tw,tv-v[i])
else
fork=0ton1do
opt[k]←cop[k]
maxV←tv-v[i]
2.2程序
//参数为物品i,当前选择已经达到的重量和tw,本方案可能达到的总价值
voidfind(inti,doubletw,doubletv)
{
intk;
//物品i包含在当前方案的可能性
if(tw+a[i].weight<=limitW)
{
cop[i]=1;
if(ifind(i+1,tw+a[i].weight,tv);
else
{
for(k=0;kopt[k]=cop[k];
maxV=tv;
}
}
cop[i]=0;
//物品i不包含在当前方案的可能性
if(tv-a[i].value>maxV)
{
if(ifind(i+1,tw,tv-a[i].value);
else
{
for(k=0;kopt[k]=cop[k];
maxV=tv-a[i].value;
}
}
}
图1、0-1背包
Hanoi塔
3.1算法
hanoi(n,a,b,c)
//Hanoi塔的移动算法
//输入:
盘子数n,起始、辅助和目标柱a、b、c
//输出:
Hanoi塔的移动步骤
ifn=1
output(a,c)
else
hanoi(n-1,a,c,b)
output(a,c)
hanoi(n-1,b,a,c)
3.2程序
voidhanoi(intn,chara,charb,charc)/*递归函数*/
{
if(n==1)
output(a,c);
else
{
hanoi(n-1,a,c,b);/*a借助b到c*/
output(a,c);
hanoi(n-1,b,a,c);/*b借助a到c*/
}
}
图2、Hanoi
棋子移动
4.1算法
move(a[1..N3],n,m)
//黑白棋的移动算法
//输入:
初始状态a[1..N3]、当前移动棋子规模n和总规模m
//输出:
棋子的移动过程
ifn=4
swap2(a[3],a[4],a[8],a[9])
output(a,m)
swap2(a[7],a[8],a[3],a[4])
output(a,m)
swap2(a[1],a[2],a[7],a[8])
output(a,m)
swap2(a[6],a[7],a[1],a[2])
output(a,m)
swap2(a[0],a[1],a[6],a[7])
output(a,m)
k3←k3+5
return
swap2(a[n-1],a[n],a[2*n],a[2*n+1])
output(a,m)
k3←k3+1
ifn<4
Error()
return
swap2(a[n-1],a[n],a[2*n-2],a[2*n-1])
output(a,m)
move(a,n-1,m)
k3←k3+1
4.2程序
voidmove(inta[N3],intn,intm)
{
if(n==4)
{
swap2(&a[3],&a[4],&a[8],&a[9]);
output(a,m);
swap2(&a[7],&a[8],&a[3],&a[4]);
output(a,m);
swap2(&a[1],&a[2],&a[7],&a[8]);
output(a,m);
swap2(&a[6],&a[7],&a[1],&a[2]);
output(a,m);
swap2(&a[0],&a[1],&a[6],&a[7]);
output(a,m);
k3+=5;
return;
}
swap2(&a[n-1],&a[n],&a[2*n],&a[2*n+1]);
output(a,m);
k3++;
if(n<4)
{
printf("error!
");
return;
}/**/
swap2(&a[n-1],&a[n],&a[2*n-2],&a[2*n-1]);
output(a,m);
move(a,n-1,m);
k3++;
}
图3、棋子移动
全排列
5.1算法
perm(list,k,m)
//全排列的生成算法
//输入:
初始数组a[1..n]、当前移动数编号k和总数目m
//输出:
全排列的所有组合
ifk>m
fori=0tomdo
output(list[i])
s←s+1
else
fori=ktomdo
swap(list[k],list[i])
perm(list,k+1,m)
swap(&list[k],&list[i])
5.2程序
voidperm(intlist[],intk,intm)
{
inti;
if(k>m)
{
for(i=0;i<=m;i++)
printf("%d",list[i]);
printf("\n");
s++;
}
else
{
for(i=k;i<=m;i++)
{
swap(&list[k],&list[i]);
perm(list,k+1,m);
swap(&list[k],&list[i]);
}
}
}
图4、全排列
约瑟夫
6.1算法
make(base,n,pos,c)
//约瑟夫的模拟算法
//输入:
初始数组a[1..n]、总人数n、淘汰位置pos和当前淘汰人数c
//输出:
约瑟夫的整个过程
j←0
ifc=n-1
output(++c,pos+1)
return
output(++c,pos+1)
base[pos]←0
whilej-k5
ifbase[pos←(pos+1)modn]
j←j+1
make(base,n,pos,c)
6.2程序
voidmake(int*base,intn,intpos,intc)
{
intj=0;
if(c==n-1)
{
printf("%d:
thelastone_NO.%dwin!
\n",++c,pos+1);
return;//出口
}
printf("%d:
NO.%d->out\n",++c,pos+1);//输出
base[pos]=0;//踢掉
while(j-k5)
if(base[pos=(pos+1)%n])
j++;//递归点,每次数到几这个k5就改到几
make(base,n,pos,c);//递归
}
图5、约瑟夫
结论
本文的设计题目是:
递归算法的应用,主要涉及
背包问题的递归
n阶hanoi塔的递归;
棋子移动的递归
出n个元素全排列的递归;
出约瑟夫问题的递归
参考文献
[1]AnanyLevitin,《算法设计与分析基础》。
清华大学出版社
[2]宋文等编,《算法设计与分析》.重庆:
重庆大学出版社,2001
[3]周培德,《算法设计与分析》.北京:
电子工业出版社,2000
[4]王晓东,《算法设计与分析》.北京:
电子工业出版社,2004