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

 更新时间:2022年01月21日 11:49:50   作者:weixin_58165485  
大家好,本篇文章主要讲的是C语言递归思想实现汉诺塔详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下

1.递归思想简介

在c语言中,程序调用自身的编程技巧称为递归( recursion)。

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

/*                                递归求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),而函数的功能如下:

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

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

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

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

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

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

递归的好处在于:

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

递归的缺点在于

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

2.汉诺塔问题

以下内容来自维基百科

最早发明这个问题的人是法国数学家爱德华·卢卡斯。

传说越南河内某间寺院有三根银棒,上串 64 个金盘。寺院里的僧侣依照一个古老的预言,以上述规则移动这些盘子;预言说当这些盘子移动完毕,世界就会灭亡。这个传说叫做梵天寺之塔问题(Tower of Brahma puzzle)。但不知道是卢卡斯自创的这个传说,还是他受他人启发。

若传说属实,僧侣们需要2^{64}-1步才能完成这个任务;若他们每秒可完成一个盘子的移动,就需要 5849 亿年才能完成。整个宇宙现在也不过 137 亿年。

这个传说有若干变体:寺院换成修道院、僧侣换成修士等等。寺院的地点众说纷纭,其中一说是位于越南的河内,所以被命名为“河内塔”。另外亦有“金盘是创世时所造”、“僧侣们每天移动一盘”之类的背景设定

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

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

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

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;
}

程序运行结果为:

总结

到此这篇关于C语言递归思想实现汉诺塔详解的文章就介绍到这了,更多相关C语言汉诺塔内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言绘制雷达图的示例代码

    C语言绘制雷达图的示例代码

    常用的统计图有条形图、柱形图、折线图、曲线图、饼图、环形图、扇形图,其中还有一种雷达图的绘制也较难,本文为大家提供了雷达图的绘制方法,需要的可以参考下
    2024-02-02
  • QT利用QPdfWriter实现绘制PDF(支持表单输出)

    QT利用QPdfWriter实现绘制PDF(支持表单输出)

    这篇文章主要为大家详细介绍了QT如何利用QPdfWriter实现绘制PDF,并可以支持表单输出。文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-01-01
  • Qt跨平台窗口选择功能的实现过程

    Qt跨平台窗口选择功能的实现过程

    很多时候为了方便软件的使用,我们需要让编写的界面程序显示在最上层,这时候就需要对窗口属性进行调整,下面这篇文章主要给大家介绍了关于Qt跨平台窗口选择功能的实现过程,需要的朋友可以参考下
    2022-12-12
  • 探讨:将两个链表非降序合并为一个链表并依然有序的实现方法

    探讨:将两个链表非降序合并为一个链表并依然有序的实现方法

    本篇文章是对将两个链表非降序合并为一个链表并依然有序的实现方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • Cocos2d-x UI开发之CCControlPotentiometer控件类使用实例

    Cocos2d-x UI开发之CCControlPotentiometer控件类使用实例

    这篇文章主要介绍了Cocos2d-x UI开发之CCControlPotentiometer控件类使用实例,本文代码中包含注释来讲解CCControlPotentiometer控件类的使用,需要的朋友可以参考下
    2014-09-09
  • C语言修炼之路灵根孕育源流出 初识C言大道生下篇

    C语言修炼之路灵根孕育源流出 初识C言大道生下篇

    C语言是一门面向过程、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言
    2022-03-03
  • C++11中lambda、std::function和std:bind详解

    C++11中lambda、std::function和std:bind详解

    大家都知道C++11中增加了许多的新特性,下面在这篇文中我们就来聊一下lambda表达式,闭包,std::function以及std::bind。文中介绍的很详细,相信对大家具有一定的参考价值,有需要的朋友们下面来一起看看吧。
    2017-01-01
  • C语言数据结构时间复杂度及空间复杂度简要分析

    C语言数据结构时间复杂度及空间复杂度简要分析

    我们在进行编程时,往往会开发诸多的算法,那么我们怎么在那么多算法中找到最好的那个呢?本文主要介绍时间和空间复杂度概念及时间复杂度的求解,预祝读者学习愉快
    2021-10-10
  • C++核心编程之内存分区模型详解

    C++核心编程之内存分区模型详解

    这篇文章主要为大家介绍了C++核心编程中内存分区模型,C++程序在执行时,将内存大方向分为四个区域,代码区,全局区,栈区,堆区,文章通过代码示例介绍的非常详细,感兴趣的同学可以参考阅读下
    2023-07-07
  • C语言 文件的随机读写详解及示例代码

    C语言 文件的随机读写详解及示例代码

    本文主要介绍C语言 文件的随机读写,这里整理了相关资料及示例代码以便大家学习参考,学习此部分内容的朋友可以参考下
    2016-08-08

最新评论