递归算法的应用.docx

上传人:b****8 文档编号:11290710 上传时间:2023-02-26 格式:DOCX 页数:15 大小:66.42KB
下载 相关 举报
递归算法的应用.docx_第1页
第1页 / 共15页
递归算法的应用.docx_第2页
第2页 / 共15页
递归算法的应用.docx_第3页
第3页 / 共15页
递归算法的应用.docx_第4页
第4页 / 共15页
递归算法的应用.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

递归算法的应用.docx

《递归算法的应用.docx》由会员分享,可在线阅读,更多相关《递归算法的应用.docx(15页珍藏版)》请在冰豆网上搜索。

递归算法的应用.docx

递归算法的应用

摘要

递归做为一种算法在程序设计语言中广泛应用。

是指函数/过程/子程序在运行过程中直接或间接调用自身而产生的重入现象。

递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写程序能使程序变得简洁和清晰。

递归的主要优点在于:

某些类型的算法采用递归比采用迭代算法要更加清晰和简单。

例如快速排序算法按照迭代方法是很难实现的。

还有其他一些问题,特别是人工智能问题,就依赖于递归提供解决方案。

最后,有些人认为递归要比迭代简单递归算法是一种直接或者间接地调用自身的算法。

在计算机编写程序中,递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于理解。

递归算法解决问题的特点:

(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

ifi

find(i+1,tw+w[i],tv)

else

fork=0ton1do

opt[k]←cop[k]

maxV←tv

cop[i]←0

iftv-v[i]>maxV

ifi

find(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(i

find(i+1,tw+a[i].weight,tv);

else

{

for(k=0;k

opt[k]=cop[k];

maxV=tv;

}

}

cop[i]=0;

//物品i不包含在当前方案的可能性

if(tv-a[i].value>maxV)

{

if(i

find(i+1,tw,tv-a[i].value);

else

{

for(k=0;k

opt[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

 

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

当前位置:首页 > 高等教育 > 艺术

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1