zoukankan      html  css  js  c++  java
  • 汉诺塔之递归与非递归解法

    1.什么是汉诺塔

    下面的定义摘自百度百科

    汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

    2.如图

    3.汉诺塔的递归解题思路

    C语言函数调用它自己,这种调用过程称为递归,递归有时候难以捉摸,有时却很方便实用,结束递归是使用递归的难点,因为如果递归代码中没有结束递归的条件测试部分,一个调用自己的函数会无限递归.所以要写出递归,关键就是找出递归的递归方程式: 也就是说,要完成最后一步,那么最后一步的前一步要做什么!
    假如A塔有n个盘子, 大小从大(底部) 到小(顶部)排列,B塔和C塔都是空塔.
    那么到底如何把这个n个盘子移动到C塔呢?

    (1)假如n=1,即就是说A塔只有1个盘子的情况下, 直接将1个盘子移动到c塔,就是把A里唯一1个盘子移动到C

    (2)n>1时,将A上面的n-1个盘子借助C塔移动到B塔,move(n-1,A,C,B)

    这里我使用了函数原型void move(int n,char A,char B,char C) (函数原型即告诉编译器函数的类型)

    (3)将A上面的最后的(最大的)盘子移动到C塔

    (4)将B上面的所有盘子(n-1)个盘子借助A塔移动到C塔,move(n-1,B,A,C)

    4.代码递归实现

    #include<stdio.h>
    #include<stdlib.h>
    void move(int n,char A,char B,char C);  // n为圆盘个数,A,B,C,分别代表三根杆子
    
    void move(int n,char A,char B,char C)
    {
     	if(n == 1)
     	    printf("%c ---> %c
    ",A,C);  //如果A杆子上只有一个圆盘,直接移动到C上
     	else
     	{
     		move(n-1,A,C,B);  //将A杆子上的n-1圆盘借助C杆子,移动到B杆子 
     		printf("%c ---> %c
    ",A,C); //将A柱子上的最后一个圆盘移动到柱子C上
     		move(n-1,B,A,C);  // 将B杆子上的n-1个圆盘,借助柱子A,移动到柱子C上
     	}	  
    } 
    
    int main(void) 
    {
    	int n;
    	printf("输入要移动的汉诺塔个数 :");
    	scanf("%d",&n);
    	move(n,'A','B','C');
           system("pause");
    }
    

    最后我想说,递归和循环,一般来说,还是选择循环比较好,首先,每次递归都会创建一组变量,所以递归使用的内存更多,而且每次递归调用都会把创建的一组新变量放在栈中.递归调用的数量受限于内存空间.而且每次函数调用都会花费一定的时间,所以递归的执行速度较慢.但在某些情况下不能用简单的循环来代替递归.

  • 相关阅读:
    Git常用命令
    Shell脚本学习
    Shell脚本学习
    Shell脚本学习
    Git ignore文件的用法
    RSA非对称加密算法
    C++ 标准库中的堆(heap)
    EM(Entity FrameWork)- code first , using in Visual stdio 2017
    C# 图片文字识别
    C# 调 C++ DLL 托管代码中释放非托管函数分配的内存
  • 原文地址:https://www.cnblogs.com/buxiu888/p/13512088.html
Copyright © 2011-2022 走看看