“双色河内塔”算法(双色汉诺塔)

问题引入

        “双色河内塔”由“河内之塔”的规则衍生而来(点击查看),区别在于双色河内塔的目的是将图1所示的圆盘位置,移动成为图2所示的圆盘位置。

图1

图2

问题分析

        “双色河内塔”最初在一根柱子上有两种颜色的圆盘从小到大交替排列,我们要进行的操作就是将两种颜色的圆环盘出来,然后放到两根柱子上,并且是从小到大放置,等同于“汉诺塔”问题。

        “双色河内塔”解法与“河内塔(单色)”类似,我们同样要进行“递回”,但是略有不同。

        先看只有两个盘的情况, 只要将第一柱的黄色移动至第二柱,而接下来第一柱的蓝色移动至第三柱,即完成了圆盘的移动,如下图。

                   

 

        接下来我们看四个盘的情况,两种颜色交替,一大一小。首先必须用递回完成下图第一个图到第二个图的移动,接下来最底层的就不用管它们了,因为它们已经就定位,只要再处理第一柱的上面两个盘子即可,如下图。

        紧接着我们看六个盘的情况,也是两种颜色交叉排列,从小到大。同样的,我们仍然是先利用“递回”的方法完成下图第一个图片到第二个图片的移动,接下来最底层的就不用管它们了,因为它们已经就定位。之后,我们只要再处理第一柱上面的四个盘子就 可以了,这又与之前只有四盘的情况相同。如下图。

 

        接下来,如果是八盘、十盘、十二盘等……,不难看出,解题的方法观念相同,只是“递回”的次数不同。

代码实现

        对问题进行了分析,那么如何编写程序呢?最主要的问题是实现“递回”,代码如下所示。

        (采用的语言为C语言,编译环境为DevC++。)

//导入头文件
#include <stdio.h>

//借助递归思想进行递回-移动
void hanoi(int disks, char source, char temp, char target){ 
    if (disks == 1){
        printf("move disk from %c to %c\n", source, target); 
        printf("move disk from %c to %c\n", source, target);
    }else {
        hanoi(disks-1, source, target, temp); 
        hanoi(1, source, temp, target); 
        hanoi(disks-1, temp, source, target);
    }
}

//使用A\B\C 表示柱子
void hanoi2colors(int disks){ 
    char source = 'A';
    char temp = 'B'; 
    char target = 'C'; 
    int i;
    for(i = disks / 2; i > 1; i--){
        hanoi(i-1, source, temp, target);
        printf("move disk from %c to %c\n", source, temp); 
        printf("move disk from %c to %c\n", source, temp); 
        hanoi(i-1, target, temp, source);
        printf("move disk from %c to %c\n", temp, target);
    }
    printf("move disk from %c to %c\n", source, temp); 
    printf("move disk from %c to %c\n", source, target);
}

//主函数
int main(){
    int n; 
    printf("请输入盘数:"); 
    scanf("%d", &n);
    hanoi2colors(n);
    return 0;
}

运行结果

 

写在最后:

        读两遍下来,如果仍然有不清楚的地方,可在评论区留言。

        如果你有其他感到困惑的问题,欢迎留言。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

等日出看彩虹

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值