汉诺塔问题程序实现代码
汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
c语言实现
#include <stdio.h>
#include <windows.h>
void Hanoi(int n, char a,char b,char c);
void Move(int n, char a, char b);
int count;
int main()
{
int n=8;
printf("请输入汉诺塔的层数:\n");
scanf(" %d",&n);
Hanoi(n, 'A', 'B', 'C');
sleep(20000);
return 0;
}
void Hanoi(int n, char a, char b, char c)
{
if (n == 1)
{
Move(n, a, c);
}
else
{
Hanoi(n - 1, a, c, b);
Move(n, a, c);
Hanoi(n - 1, b, a, c);
}
}
void Move(int n, char a, char b)
{
count++;
printf("第%d次移动 Move %d: Move from %c to %c !\n",count,n,a,b);
}
汉诺塔问题的非递归实现
#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("\t");
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("\n");
}
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\t",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\t",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;
}
递归实现
#include <iostream>
using namespace std;
template<int n>
void hanoi(char a, char b, char c){
hanoi<n - 1>(a, c, b);
printf("%c -> %c\n", a, c);
hanoi<n - 1>(b, a, c);
}
template<>
void hanoi<1>(char a, char b, char c){
printf("%c -> %c\n", a, c);
}
////////////////////////////////////////////////
template<int n, char a, char b, char c>
class hanoi1{
public:
static int hanoi(){
hanoi1<n-1, a, c, b>::hanoi();
printf("%c -> %c\n", a, c);
hanoi1<n-1, b, a, c>::hanoi();
}
};
template<char a, char b, char c>
class hanoi1<1, a, b ,c>{
public:
static int hanoi(){
printf("%c -> %c\n", a, c);
}
};
int main(){
#define N 4
cout<<"类模板偏特化:";
hanoi1<N,'A','B','C'>::hanoi();
cout<<endl;
cout<<"函数模板全特化:";
hanoi<3>('A','B','C');
exit(0);
}
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');
}
}
php
简单的用php实现了汉诺塔问题的求解,使用递归调用,但是用php实现要是盘子的个数很多的话,运行起来会很慢的...
汉诺塔主要是有三个塔座X,Y,Z,要求将三个大小不同,依小到大编号为1,2.....n的圆盘从A移动到塔座Z上,要求
(1):每次只能移动一个圆盘
(2):圆盘可以插到X,Y,Z中任一塔座上
(3):任何时候不能将一个较大的圆盘压在较小的圆盘之上
主要是运用了递归的思想,这里使用php做个简单的实现......
<?php
function hanoi($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);
}
}
function move($x,$n,$z){
echo'movedisk'.$n.'from'.$x.'to'.$z.'<br>';
}
hanoi(10,'x','y','z');
?>
pascal
var m:integer;
procedure move(getone,putone:char);
begin writeln(getone,'->',putone) end;
procedure hanoi(n:integer;one,two,three:char);
begin
if n=1 then move(one,three) else
begin
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three)
end
end;
begin
readln(m);
write('the step to moving disks:');
writeln;
hanoi(m,'A','B','C')
end.
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')
lua
function hanoi(num, a,b,c)
if (num == 1) then
print(a .."-->"..c)
else
hanoi(num-1, a,c,b)
print(a .."-->"..c)
hanoi(num-1, b,a,c)
end
end
hanoi(3,'A','B','C')
JavaScript
var hanoi=function(n,from,ass,to){
if(n==1){
move(from,to);
}else{
hanoi(n-1,from,to,ass);
move(from,to);
hanoi(n-1,ass,from,to);
}
}
var move=function(from,to){
console.log("从"+from+"到"+to);
}
hanoi(3,"A","B","C");