zoukankan      html  css  js  c++  java
  • 汉诺塔的递归和非递归实现

     汉诺塔的递归和非递归实现 

    借助堆栈以非递归(循环)方式求解汉诺塔的问题(n, a, b, c),即将N个盘子从起始柱(标记为“a”)通过借助柱(标记为“b”)移动到目标柱(标记为“c”),并保证每个移动符合汉诺塔问题的要求。

    输入格式:

    输入为一个正整数N,即起始柱上的盘数。

    输出格式:

    每个操作(移动)占一行,按柱1 -> 柱2的格式输出。

    输入样例:

    3
    

    输出样例:

    a -> c
    a -> b
    c -> b
    a -> c
    b -> a
    b -> c
    a -> c

    代码:(递归算法)
    ps:函数hanoi里的n是n个盘子,move函数里的n是第n个
     1 #include <stdio.h>
     2 int i=1;//记录步数
     3 void move(int n,char x,char y) //将编号为n的盘子由from移动到to
     4 {
     5     printf("将%d号盘子%c---->%c
    ",n,x,y);
     6 }
     7 void hanoi(int n,char x,char y,char z)//将n个盘子由初始塔移动到目标塔(利用借用塔)
     8 {
     9     if (n==1)
    10         move(1,x,z);//只有一个盘子是直接将初塔上的盘子移动到目的地
    11     else
    12     {
    13         hanoi(n-1,x,z,y);//先将初始塔的前n-1个盘子借助目的塔移动到借用塔上
    14         move(n,x,z);              //将剩下的一个盘子移动到目的塔上
    15         hanoi(n-1,y,x,z);
    16         //最后将借用塔上的n-1个盘子移动到目的塔上
    17     }
    18 }
    19 int main()
    20 {
    21     printf("请输入盘子的个数:
    ");
    22     int n;
    23     scanf("%d",&n);
    24     char x='A',y='B',z='C';
    25     printf("盘子移动情况如下:
    ");
    26     hanoi(n,x,y,z);
    27     return 0;
    28 }
    
    

    递归的算法,简洁一点也可以这样写:

    void Hanoi(int n,char A,char B,char C)  //A借助B,将n个盘子移到C ,递归的妙用在于不用关心具体实现的细节
    {
        if (n==1)printf("%c -> %c",A,C); //只有一个盘子,直接将其移到C
        else
        {
            Hanoi(n-1,A,C,B);  //第一步,A借助C,将n-1个盘子移到B;
            printf("%c -> %c",A,C);   //第二步,将A上剩余的一个盘移到C;
            Hanoi(n-1,B,A,C)  //第三步,将B上的n-1个盘子移到C。
        }
    }

    坦白说,关于非递归的算法,没什么思路,就是用递归算法跑一些数值,想出来的算法也不是特别好

    代码:(非递归算法)

     1 #include<iostream>  
     2 #include<algorithm>  
     3 #include <stack>  
     4 #include <cstdio>  
     5 #include<cmath>  
     6 using namespace std;  
     7 int temp1=-1, temp2=-1;  
     8 char s[4] = { 'q','a','b','c' };//为了解题简便,我是从1开始算的  
     9 stack<int> a[4];  
    10 int c1 = 0;  
    11 int rank1[4];  
    12 bool compare(int a1,int b1) 
    13 { //给栈顶元素排序用  
    14     if (a[a1].top() >= a[b1].top())  
    15         return true;  
    16     if (a[a1].top() < a[b1].top())  
    17         return false;  
    18     return false;  
    19 }  
    20 bool move1(int before,int after) {   //移动物块  
    21     if ((a[after].top() - a[before].top())%2==0)  
    22         return false;  
    23     a[after].push(a[before].top());  
    24     a[before].pop();  
    25     temp1 = before; temp2 = after;  //记录上一次移动的物块位置  
    26     printf("%c -> %c
    ",s[temp1],s[temp2]);
    27     c1++;  
    28     return true;  
    29 }  
    30 int main(){  
    31     int i, N;  
    32     cin >> N;//起始柱上的盘数
    33     a[1].push(N+1);//保证栈不会为空  
    34     for (i = 0; i < N; i++)  
    35         a[1].push(N-i);   //初始化  
    36     a[2].push(N + 2);  
    37     a[3].push(N+3);  
    38     if (N % 2 == 1) {        //N为奇数还是偶数,第一次移物块到哪里是不同的  
    39         move1(1, 3);  
    40         temp1 = 1;  
    41         temp2 = 3;  
    42     }  
    43     else {  
    44         move1(1, 2);  
    45         temp1 = 1; temp2 = 2;  
    46     }  
    47     for (i = 1; i <= 3; i++)//初始化栈排序表  
    48         rank1[i] = i;  
    49     int tt;  
    50     while (c1 < pow(2, N) -1) {  
    51         sort(rank1 + 1, rank1 + 4, compare);//按compare函数排序  
    52             if (temp2 == rank1[2]) { //刚移动过的物块不会再被移动  
    53                 if(tt==temp1)   //别问我为什么,找规律找出来的  
    54                     move1(rank1[3], rank1[2]);  
    55                 else  
    56                     move1(rank1[3], rank1[1]);  
    57             }  
    58             else  
    59                 move1(rank1[2], rank1[1]);  
    60         tt = rank1[2];   
    61     }  
    62 }  
  • 相关阅读:
    路径查看linux 向内核注册总线例子
    属性应用Android Manifest之<provider>元素中文注释
    序数序列hdu 1394
    大分类分类Zen Cart大分类下直接显示产品列表插件
    虚拟化运行[OpenStack] VMWare产品介绍
    名称磁盘Linux系统监控的CPU、Mem、IO的OID
    端口服务器黑马韩前成linux从入门到精通proftpd服务器配置
    主库配置关于Dataguard Online redo log 和 Standby redo log
    尺寸品牌Jquery 仿淘宝京东多条件筛选 可自行结合ajax加载
    设置编辑(iPhone/iPad开发)设置UITextView为不可编辑状态
  • 原文地址:https://www.cnblogs.com/guohaoyu110/p/6360120.html
Copyright © 2011-2022 走看看