汉诺塔问题

算法:当只有一个盘子的时候,只需要从将A塔上的一个盘子移到C塔上。

  当A塔上有两个盘子是,先将A塔上的1号盘子(编号从上到下)移动到B塔上,再将A塔上的2号盘子移动的C塔上,最后将B塔上的小盘子移动到C塔上。

  当A塔上有3个盘子时,先将A塔上编号1至2的盘子(共2个)移动到B塔上(需借助C塔),然后将A塔上的3号最大的盘子移动到C塔,最后将B塔上的两个盘子借助A塔移动到C塔上。

  当A塔上有n个盘子是,先将A塔上编号1至n-1的盘子(共n-1个)移动到B塔上(借助C塔),然后将A塔上最大的n号盘子移动到C塔上,最后将B塔上的n-1个盘子借助A塔移动到C塔上。

  综上所述,除了只有一个盘子时不需要借助其他塔外,其余情况均一样(只是事件的复杂程度不一样)。

         

Python

def hanoi(n,x,y,z):
    if n==1:
        print(x,'-->',z)
    else:
        hanoi(n-1,x,z,y)#将前n-1个盘子从x移动到y上
        hanoi(1,x,y,z)#将最底下的最后一个盘子从x移动到z上
        hanoi(n-1,y,x,z)#将y上的n-1个盘子移动到z上
n=int(input('请输入汉诺塔的层数:'))
hanoi(n,'x','y','z')

php

<?php
 
functionhanoi($n,$x,$y,$z){
 
if($n==1){
 
move($x,1,$z);
 
}else{
 
hanoi($n-1,$x,$z,$y);
 
move($x,$n,$z);
 
hanoi($n-1,$y,$x,$z);
 
}
 
}
 
functionmove($x,$n,$z){
 
echo'movedisk'.$n.'from'.$x.'to'.$z.'<br>';
 
}
 
hanoi(10,'x','y','z');
 
?>

Java

public class Hanoi {
    /**
    * 
    * @param n 盘子的数目
    * @param origin 源座
    * @param assist 辅助座
    * @param destination 目的座
    */
    public void hanoi(int n, char origin, char assist, char destination) {
        if (n == 1) {
            move(origin, destination);
        } else {
            hanoi(n - 1, origin, destination, assist);
            move(origin, destination);
            hanoi(n - 1, assist, origin, destination);
        }
    }
 
    // Print the route of the movement
    private void move(char origin, char destination) {
        System.out.println("Direction:" + origin + "--->" + destination);
    }
 
    public static void main(String[] args) {
        Hanoi hanoi = new Hanoi();
        hanoi.hanoi(3, 'A', 'B', 'C');
    }
}

C++

#include<iostream>
using namespace std;
void hanoi(int n,char a,char b,char c)
{
if(n==1)
cout<<n<<" "<<a<<" "<<c<<endl;
else
{
hanoi(n-1,a,c,b);
cout<<n<<" "<<a<<" "<<c<<endl;
hanoi(n-1,b,a,c);
}
}
int main()
{
int n;
cout<<"输入正整数:"<<endl;
cin>>n;
cout<<"结果为"<<endl;
hanoi(n,'A','B','C');
return 0;
} 

C语言

#include<stdio.h>
voidhanoi(intn,charA,charB,charC)
{
 
if(n==1)
{
printf("Movedisk%dfrom%cto%c
",n,A,C);
}
else
{
hanoi(n-1,A,C,B);
printf("Movedisk%dfrom%cto%c
",n,A,C);
hanoi(n-1,B,A,C);
}
}
main()
{
intn;
printf("请输入数字n以解决n阶汉诺塔问题:
");
scanf("%d",&n);
hanoi(n,'A','B','C');
return 0;
}

汉诺塔问题的非递归实现

#include<stdio.h>
#include<math.h>
#include<stdlib.h>
//第0位置是柱子上的塔盘数目
intzhua[100]={0},zhub[100]={0},zhuc[100]={0};
charcharis(charx,intn)
//左右字符出现顺序固定,且根据n值奇偶尔不同
{
switch(x)
{
case'A':
return(n%2==0)?'C':'B';
case'B':
return(n%2==0)?'A':'C';
case'C':
return(n%2==0)?'B':'A';
default:
return'0';
}
}
voidprint(charlch,charrch)
//打印字符
{
if(lch=='A')
{
switch(rch)
{
case'B':
zhub[0]++;
zhub[zhub[0]]=zhua[zhua[0]];
zhua[zhua[0]]=0;
zhua[0]--;
break;
case'C':
zhuc[0]++;
zhuc[zhuc[0]]=zhua[zhua[0]];
zhua[zhua[0]]=0;
zhua[0]--;
break;
default:
break;
}
}
if(lch=='B')
{
switch(rch)
{
case'A':
zhua[0]++;
zhua[zhua[0]]=zhub[zhub[0]];
zhub[zhub[0]]=0;
zhub[0]--;
break;
case'C':
zhuc[0]++;
zhuc[zhuc[0]]=zhub[zhub[0]];
zhub[zhub[0]]=0;
zhub[0]--;
break;
default:
break;
}
}
if(lch=='C')
{
switch(rch)
{
case'A':
zhua[0]++;
zhua[zhua[0]]=zhuc[zhuc[0]];
zhuc[zhuc[0]]=0;
zhuc[0]--;
break;
case'B':
zhub[0]++;
zhub[zhub[0]]=zhuc[zhuc[0]];
zhuc[zhuc[0]]=0;
zhuc[0]--;
break;
default:
break;
}
}
printf("	");
inti;
printf("(");
for(i=1;i<=zhua[0];i++)
printf("%d",zhua[i]);
printf(")");
printf("(");
for(i=1;i<=zhub[0];i++)
printf("%d",zhub[i]);
printf(")");
printf("(");
for(i=1;i<=zhuc[0];i++)
printf("%d",zhuc[i]);
printf(")");
printf("
");
}
voidHannuo(intn)
{
//分配2^n个空间
bool*isrev;
isrev=(bool*)malloc(sizeof(bool)*(int)pow(2,n));
for(inti=1;i<pow(2,n);i++)
isrev[i]=false;
//循环计算是否逆序
for(intci=2;ci<=n;ci++)
{
for(intzixh=(int)pow(2,ci-1);zixh<pow(2,ci);zixh+=4//初始值重复一次,自增值可加4,减少循环次数。
isrev[zixh]=isrev[(int)pow(2,ci)-zixh];
//该位置为中间位置,且奇次幂逆序,偶数幂不逆序
isrev[(int)pow(2,ci)]=((ci-1)%2==0)?false:true;
}
charlch='A',rch;
rch=(n%2==0?'B':'C');
printf("%d	",1);
printf("%c->%c",lch,rch);
print(lch,rch);
for(intk=2;k<pow(2,n);k++)
{
if(k%2==0)
rch=charis(lch,n);
else
lch=charis(rch,n);
printf("%d	",k);
if(isrev[k])
{
printf("%c->%c",rch,lch);
print(rch,lch);
}
else
{
printf("%c->%c",lch,rch);
print(lch,rch);
}
}
}
intmain()
{
intn;
printf("Inputthenum:");
scanf("%d",&n);
zhua[0]=n;
for(inti=1;i<=n;i++)
zhua[i]=n-i+1;
Hannuo(n);
return0;
}
原文地址:https://www.cnblogs.com/lswit/p/4574388.html