0
点赞
收藏
分享

微信扫一扫

C语言递归思想实现汉诺塔

吃面多放酱 2022-01-20 阅读 205

目录

1.递归思想简介

2.汉诺塔问题

3.汉诺塔递归的c语言实现


1.递归思想简介

递归的定义看上去似乎很抽象,使用代码描述能够让人容易理解,下面是一个函数递归的例子。

/*                                递归求n的阶乘                        */


int factorial(int n)  //定义一个求阶乘的函数叫做factorial(),需要一个整形参数,返回一个整形值
{
	if (n <= 1)       //递归结束的条件
	{
		return 1;
	}
	else
	{
		return n * factorial(n - 1);//在factorial()中再次调用自身,只不过参数由n变成n-1
	}	
}

在这个例子中,函数 factorial()接收到一个整形数n,如n=5,暂时称作F(5),这时n!=F(5),而函数的功能如下:

  1. 判断5是否小于或等于1,如果是,将1返回;不是,进到else执行语句
  2. 返回(这里可以将return看作等于)5× factorial(n - 1),等价于 F(5)=5×F(4)
  3. 用上面的方法计算F(4)=4×F(3)
  4. ....以此类推直到达到限制条件n=1时有,F(1)=1

递归算法的实质:是把问题转化为规模缩小了的同类问题的子问题。然后递归调用函数(或过程)来表示问题。

由于每个小问题处理起来都有与大问题类似的行为逻辑,因此我们可以“大事化小”,而递归说白了,就是不断地在套娃。

但是,计算机的内存是有限的,由于每次调用函数都需要在栈区开辟一个空间,使得递归不能无限制地进行下去,没有递归结束的条件,当操作系统为进程分配的虚拟地址空间当中的栈空间被耗尽时,会发生堆栈溢出,产生段错误(segmentation fault)。

因此,使用递归时应注意:

  • 必须存在限制条件,当满足这个限制条件的时候,递归便不再继续
  • 每次递归调用之后越来越接近这个限制条件 

递归的好处在于:

  • 代码简洁
  • 在某些特定问题上求解方便

递归的缺点在于

  • 消耗大量时间和空间资源——效率较低
  • 可能伴随许多重复计算,工作量大——影响性能

2.汉诺塔问题

以下内容来自维基百科

汉诺塔基本的玩法如图,其规则是:将圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。 

 当圆盘数量只有3个的时候,求解的方法显而易见,但当数量增多时,问题变得有些棘手起来。但不管怎么移动,核心思想都是递归:

  1. 先从n块圆盘中将最大的一块移动到最后的柱子上
  2. 接着从剩下n-1找到最大的一块移到柱子上
  3. ...... 

3.汉诺塔递归的c语言实现

C语言代码如下:

/*                            汉诺塔问题(递归实现)                     */


#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void move(char, char); // 声明一个函数move,函数定义在下方,用于表示圆盘的交换

void Towers_Of_Hanoi(int n,char a,char b,char c) 
{
	if (1 == n)                        //递归结束标志:当柱子上只有一块圆盘
	{
		move(a, c);                    //从a移动到c
	}
	else
		Towers_Of_Hanoi(n - 1, a, c, b);    //将最上面n-1个圆盘移动到b柱上
		move(a, c);                         //将a上面最后一块圆盘移动到c柱上
		Towers_Of_Hanoi(n - 1, b, a, c);    //将b柱上n-1个圆盘移动到a柱上
	}
}

void move(char x, char y)
{
	printf("%c-->%c\n", x, y);
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	Towers_Of_Hanoi(n, 'A', 'B', 'C');//n为A柱子上圆盘的数量,A,B,C代表三根柱子
	return 0;
}

程序运行结果为:

 ​​​​

 

举报

相关推荐

0 条评论