Hanoi塔问题是个古典的数学问题,如果能够想清楚这个问题,那我相信你的逻辑思维已经很不错了,问题是这样的:
古代有一个梵塔,塔内三个座A,B,C,A上有64个盘子,从小到大,从上而下依次排列,有人想把这64个盘子从A移动到C,每次只能移动一个盘子,并且移动过程中始终保持三个座上小盘在上,大盘在下,请问该怎么移动?
刚拿到这个问题,绝对是很难从头到尾想清楚详细的步骤,当然除非你的大脑比电脑的运算能力还要强千百倍,那就不用再往下看了,首先我们可以假设:
如果有另外一个人帮我把63个盘子从A移动到B,那么我就可以只移动1个盘子从A到C,然后再让这个人帮我把63个盘子从B移动到C,不就实现了吗?那么问题来了,第二个人又要怎样将盘子从A移动到B,他就只能叫第三个人帮他将62个盘子从A移动到C,那么他就可以将1个盘子从A移动到B,然后再让第三个人将62 个盘子从C移动到B……以此类推
这样大概的步骤就有点轮廓了,下面就是程序了,虽然我们知道这个步骤,但是这个递归程序到底该怎么写呢?
(1)叫第二个人将n-1个盘子从A移动到B
(2)自己将1个盘子从A移动到C
(3)叫第三个人将n-1个盘子从B移动到C
我们想象一下,第一个人将n个盘子从A移动到C,首先需要第二个人将n-1个盘子从A移动到B,而第二个人将n-1个盘子从A移动到B,又需要第三个人将n-2个盘子从A移动到C,所以我们会发现在完成第一步的过程中,他们一直是将盘子从A到B和C之间不停的切换。
而第三步,第二个人需要将n-1个盘子从B移动到C,首先我们需要第三个人将n-2个盘子从B移动到A,然后他才能将一个盘子从B移动到C,接着第三个人需要将n-2个盘子从A移动到C,首先他需要第四个人将n-3个盘子从A移动到B,然后他才可以将一个盘子从A移动到C,以此类推,我们可以发现第三步其实都是A,B座来回切换。
那么我们就可以这样编写程序了
(1)定义我们自己移动盘子的函数
void move(char x , char y)(2)定义下一个人需要移动盘子的函数
32 {
33 printf("%c ——> %c \n", x , y);
35 }
- 叫第二个人将n-1个盘子从A通过C移动到B
- 自己将1个盘子从A移动到C
- 叫第三个人将n-1个盘子从B通过A移动到C
void hanoi(int i , char A , char B , char C) 函数(盘子个数,开始点,过度点,最终点)
18 {
19 if(i == 1)
20 {
21 move(A , C);
22 }
23 else
24 {
25 hanoi(i - 1 , A , C , B); 叫第二个人将n-1个盘子从A通过C移动到B
26 move(i , A , C); 自己将1个盘子从A移动到C
27 hanoi(i - 1 , B , A , C); 叫第三个人将n-1个盘子从B通过A移动到C
28 }
29 }
C程序:
#include <stdio.h>java 程序
2
3 void hanoi(int i , char A , char B , char C);
4 void move(char x , char y);
5
6 int main()
7 {
8 int n ;
9 printf("请输入n的值:");
10 scanf("%d",&n);
11
12 hanoi(n , 'A' , 'B' , 'C');
13
14 return 0 ;
15 }
16
17 void hanoi(int i , char A , char B , char C)
18 {
19 if(i == 1)
20 {
21 move(A , C);
22 }
23 else
24 {
25 hanoi(i - 1 , A , C , B); //B C座切换
26 move(i , A , C);
27 hanoi(i - 1 , B , A , C); //A B座切换
28 }
29 }
30
31 void move(char x , char y)
32 {
33 printf("%c ——> %c \n", x , y);
35 }
import java.util.Scanner;
public class Move {
public static void main(String[] args) {
System.out.println("input the number of diskes:");
Scanner scan = new Scanner(System.in);
Integer m = Integer.valueOf(scan.nextLine());
Move move = new Move();
move.hanoi(m,'a', 'b','c');
}
public void move(char x,char y){
System.out.println(x+"--->"+y);
}
public void hanoi(int n,char one,char two,char three){
if(n==1){
move(one,three);
}
else{
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
}
将2个盘子移动到C,需要3步
将3个盘子移动到C,需要7步