递归:简单的讲,就是定义一个过程或函数时出现调用本过程或本函数就称为递归。 典型的例子: 求阶乘:
int fun(int n) {
if(n == 1)
return(1);
else
return fun(n*fun(n - 1));
}
(1) 从上例就可以看出,递归需要终止递归的结束条件。 (2) 递归的次数必须是有限次的 (3) 可以将一个大的问题转化为一个或多个与原问题相似规模较小的子问题,而这些小问题求解方法与原问题相同。
如,Fibonacci数列:
int Fib(int n) {
if(n == 1 || n == 2)
return (1);
else
return (Fib(n - 1) + Fib(n - 2));
}
如,汉罗塔问题:
void Hanio(int n, char x, char y, char z)
{
if (n == 1)
printf("第%d个盘子:%c-->%c\n", n, x, z);
else {
Hanio(n - 1, 'x', 'z', 'y'); // 此时x=x,y=y,z=z
printf("第%d个盘子:%c-->%c\n", n, x, z);
Hanio(n - 1, 'y', 'x', 'z'); //此时 x=y,y=z,z=z
}
}
递归模型一般分为两部分:递归结束出口和递归体。在递归体过程中,一般分为两部分,对递归问题分解和求值两部分。 如 阶乘递归:以fun(5)为例 5的阶乘分解和求解过程
(1) 首先,在大问题(第n个问题)假设合理的小问题(第n-1个问题) (2) 确定n与n-1之间的关系,也就是确定递归体。 (3) 找到合理的出口,如n=0或者n=1时的解。
用栈来实现汉罗塔:
#include<stdio.h>
#include<iostream>
#include<cstdlib>
using namespace std;
#define Max 50
typedef struct {
int n; //表示有多少个盘子
char x;
char y;
char z;
bool move_flag; //表示这个元素是否可以移动。 当n=1时是可以移动的
}ElemType;
typedef struct {
ElemType data[Max];
int top;
}StackHanio;
//初始化栈
void InitStack(StackHanio &s) {
s.top = -1;
}
//判断栈是否为空
bool Stackempty(StackHanio s){
return(s.top == -1);
}
//元素入栈
void Push(StackHanio &s, ElemType e) {
if (s.top == Max - 1)
exit(1);
else{
s.top++;
s.data[s.top] = e;
}
}
//元素出栈
void Pop(StackHanio &s, ElemType &e) {
if (s.top == -1)
exit(1);
else {
e = s.data[s.top];
s.top--;
}
}
void Hanio(int n1, char x, char y, char z) {
StackHanio s;
InitStack(s);
ElemType e, e1, e2, e3;
e.x = 'X', e.y = 'Y', e.z = 'Z', e.n = n1, e.move_flag = false;
Push(s, e);
while (!Stackempty(s)) {
Pop(s,e);
if (e.move_flag == false) {
e3.n = e.n - 1, e3.x = e.y, e3.y = e.x, e3.z = e.z;
if (e3.n == 1)
e3.move_flag = true;
else
e3.move_flag = false;
Push(s, e3); //相当于Hanio(n-1,y,x,z)
e2.n = e.n, e2.x = e.x, e2.y = e.y, e2.z = e.z,e2.move_flag=true;
Push(s, e2); //mov(n,x,z)
e1.n = e.n - 1, e1.x = e.x, e1.y = e.z, e1.z = e.y;
if (e1.n == 1)
e1.move_flag = true;
else
e1.move_flag = false;
Push(s, e1); //Hanio(n-1,x,z,y)
}
else
cout << "第" <<e.n<< "个盘片:" <<e.x<< "-->" << e.z << "\n";
}
}
int main() {
Hanio(3, 'X', 'Y', 'Z');
system("pause");
return 0;
}
[注]: 如果我们用递归实现汉罗塔时: 将x上n个盘子借助y移动到z上 一般有以下三步: (1)Hanio(n-1,x,z,y) (2)mov(n,x,z) (3)Hanio(n-1,y,x,z) 若使用栈时:由于栈是后进先出这种特性; 所以在代码实现时与递归实现的(1)和(3)反过来啦,请读者自行体会:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/182998.html原文链接:https://javaforall.cn