有A、B和C 3跟柱子,在A上从下往上按照从小到大的顺序放着64个圆盘,以B为中介,把盘子全部移动到C上。移动过程中,要求任意盘子的下面要么没有盘子,要么只能有比它大的盘子。
* 思想:采用递归的方法来接
* 1. 先将A上面的n-1个盘子,移到B柱上
* 2. 然后把A上最大的一个盘子放到C上去
* 3. 然后把B上面的n-1个盘子移到A上去
*
* 步骤:
* 汉若塔用递归思考首先考虑一种临界状态,把n-1个上面的盘从A—B, 就是把n从A移动到C,最后把n-1个盘从B---C,
* (注意在考虑把n-1个盘从B---C的时候就出现递归调用,如果把A,B盘交换就又重复上面的流程了,最后到n = 1的时候就返回)
*
* 伪代码:
* public void run(int n, char a, char b, char c)
{
if(n==1)
{
move(n,a,c) //等于1的时候把盘从A移动到C
}else
{
run(n-1,a,b,c);//递归调用把a上面的n-1个盘移动到B上,怎么表示移动?把柱子交换不就是移动了。
move(n,a,c);
run(n-1,b,a,c);//意图是把n-1个盘从B移动到A上。
}
}
*
package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
public class StringNumber {
public static void main(String args[]) throws Exception {
int n;
BufferedReader buf =
new BufferedReader(new InputStreamReader(System.in));
System.out.print("请输入盘数:");
n = Integer.parseInt(buf.readLine());
StringNumber hanoi = new StringNumber();
hanoi.move(n, 'A', 'B', 'C');
}
public void move(int n, char a, char b, char c) {
if (n == 1)
System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
else {
move(n - 1, a, c, b);
System.out.println("盘 " + n + " 由 " + a + " 移至 " + c);
move(n - 1, b, a, c);
}
}
}
输出:
请输入盘数:5
盘 1 由 A 移至 C
盘 2 由 A 移至 B
盘 1 由 C 移至 B
盘 3 由 A 移至 C
盘 1 由 B 移至 A
盘 2 由 B 移至 C
盘 1 由 A 移至 C
盘 4 由 A 移至 B
盘 1 由 C 移至 B
盘 2 由 C 移至 A
盘 1 由 B 移至 A
盘 3 由 C 移至 B
盘 1 由 A 移至 C
盘 2 由 A 移至 B
盘 1 由 C 移至 B
盘 5 由 A 移至 C
盘 1 由 B 移至 A
盘 2 由 B 移至 C
盘 1 由 A 移至 C
盘 3 由 B 移至 A
盘 1 由 C 移至 B
盘 2 由 C 移至 A
盘 1 由 B 移至 A
盘 4 由 B 移至 C
盘 1 由 A 移至 C
盘 2 由 A 移至 B
盘 1 由 C 移至 B
盘 3 由 A 移至 C
盘 1 由 B 移至 A
盘 2 由 B 移至 C
盘 1 由 A 移至 C
①如果只能移动到相邻的 那么n个圆盘需要
f(n)=(3^n)-1 次
②如果不加上只能移动到相邻的限制的话 那么n个圆盘需要f(n)=(2^n)-1次
- public class Hanoi {
- /**
- * @count记录是第几次移动
- */
- private static int count = 0;
- /**
- * @Describe_将塔座x上按直径大小自上而下编码为123...n个圆盘按规则一到塔座Z上_y做辅助塔座
- * @param n圆盘的格式
- * @param x起始圆盘的位置
- * @param y辅助塔座
- * @param z目标塔座
- */
- public static void hanoi(int n, char x, char y, char z) {
- if (n == 1) {
- move(x, 1, z);//
- } else {
- hanoi(n - 1, x, z, y);// 将前n-1个从x移动到y,z当辅助
- move(x, n, z);// 将变化为n的圆盘从x移动到z
- hanoi(n - 1, y, x, z);// 再将前n-1个圆盘从y移动到z,x当辅助
- }
- }
- /**
- * @Describe_移动操作_将编号为n的圆盘从x移动到z
- * @param x
- * @param n
- * @param z
- */
- public static void move(char x, int n, char z) {
- System.out.println("第 " + (++count) + "次移动 :" + n + "号圆盘," + x + "-->"
- + z);
- }
- /**
- * @Describe_规则再次变化_再加上一个只能移动到相邻的限制条件
- * @param n
- * @param x
- * @param y
- * @param z
- */
- public static void hanoi2(int n, char x, char y, char z) {
- if (n == 1) {
- move(x, 1, y);//
- move(y, 1, z);//
- } else {
- hanoi2(n - 1, x, y, z);// 将前n-1个从x移动到z,y当辅助
- move(x, n, y);// 将变化为n的圆盘从x移动到y
- hanoi2(n - 1, z, y, x);// 再将前n-1个圆盘从z移动到x,y当辅助
- move(y, n, z);// 将变化为n的圆盘从y移动到z
- hanoi2(n - 1, x, y, z);// 将前n-1个从x移动到z,y当辅助
- }
- }
- public static void main(String[] args) {
- // Hanoi.hanoi(4, 'x', 'y', 'z');//------可以移动到相邻的或者不相邻的
- // Hanoi.hanoi2(4, 'x', 'y', 'z');//-----只能移动到相邻的
- }
- }
用栈实现:
package cglib;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Stack;
public class StringNumber {
//塔
class Tower<E> {
//塔编号
private int number;
//塔名称
private String name;
//存放盘子的栈
private Stack<E> stack = new Stack<E>();
public Tower(int number,String name) {
this.number = number;
this.name = name;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
public Stack<E> getStack() {
return stack;
}
}
//盘子
class Tray {
//盘子编号
private int number;
//盘子名称
private String name;
public Tray(int number,String name) {
this.number = number;
this.name = name;
}
public int getNumber() {
return number;
}
public String getName() {
return name;
}
public String toString() {
return name;
}
}
public <T> void hanoi(int num,Tower<T> from,Tower<T> middle,
Tower<T> to) {
if(num == 1) {
move(from,middle,to);
} else {
//将num-1个盘子从from塔上移到middle塔上
hanoi(num-1,from,to,middle);
//将第num个盘子移到to塔上
move(from,middle,to);
//将num-1个盘子从middle塔上移到to塔上
hanoi(num-1,middle,from,to);
}
}
private <E> void move(Tower<E> from,Tower<E> middle ,Tower<E> to) {
E tray = from.getStack().pop();
to.getStack().push(tray);
StringBuilder sb = new StringBuilder();
sb.append("=====================Hanoi.move()======================\n")
.append(" Move tray : ").append(((Tray)tray).getName())
.append(" from ").append(from.getName()).append(" to ")
.append(to.getName()).append("\n ")
.append(from.getName()).append(":").append(format(from)).append(",")
.append(middle.getName()).append(":").append(format(middle)).append(",")
.append(to.getName()).append(":").append(format(to));
System.out.println(sb.toString());
}
private <E> String format(Tower<E> tower) {
Iterator<E> i = tower.getStack().iterator();
if (! i.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
while(i.hasNext()) {
sb.append(i.next().toString()).append(",");
}
sb.replace(sb.length()-1, sb.length(), "]");
return sb.toString();
}
public static void main(String[] args) {
StringNumber hanoi = new StringNumber();
Tower<Tray> from = hanoi.new Tower<Tray>(1, "1号塔");
Tower<Tray> middle = hanoi.new Tower<Tray>(2, "2号塔");
Tower<Tray> to = hanoi.new Tower<Tray>(3, "3号塔");
int num = 4;
for (int i = num; i >0; i--) {
Tray tray = hanoi.new Tray(i,i+"号盘子");
from.getStack().push(tray);
}
hanoi.hanoi(num, from, middle, to);
}
}
输出:=====================Hanoi.move()======================
Move tray : 1号盘子 from 1号塔 to 2号塔
1号塔:[4号盘子,3号盘子,2号盘子],3号塔:[],2号塔:[1号盘子]
=====================Hanoi.move()======================
Move tray : 2号盘子 from 1号塔 to 3号塔
1号塔:[4号盘子,3号盘子],2号塔:[1号盘子],3号塔:[2号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 2号塔 to 3号塔
2号塔:[],1号塔:[4号盘子,3号盘子],3号塔:[2号盘子,1号盘子]
=====================Hanoi.move()======================
Move tray : 3号盘子 from 1号塔 to 2号塔
1号塔:[4号盘子],3号塔:[2号盘子,1号盘子],2号塔:[3号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 3号塔 to 1号塔
3号塔:[2号盘子],2号塔:[3号盘子],1号塔:[4号盘子,1号盘子]
=====================Hanoi.move()======================
Move tray : 2号盘子 from 3号塔 to 2号塔
3号塔:[],1号塔:[4号盘子,1号盘子],2号塔:[3号盘子,2号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 1号塔 to 2号塔
1号塔:[4号盘子],3号塔:[],2号塔:[3号盘子,2号盘子,1号盘子]
=====================Hanoi.move()======================
Move tray : 4号盘子 from 1号塔 to 3号塔
1号塔:[],2号塔:[3号盘子,2号盘子,1号盘子],3号塔:[4号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 2号塔 to 3号塔
2号塔:[3号盘子,2号盘子],1号塔:[],3号塔:[4号盘子,1号盘子]
=====================Hanoi.move()======================
Move tray : 2号盘子 from 2号塔 to 1号塔
2号塔:[3号盘子],3号塔:[4号盘子,1号盘子],1号塔:[2号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 3号塔 to 1号塔
3号塔:[4号盘子],2号塔:[3号盘子],1号塔:[2号盘子,1号盘子]
=====================Hanoi.move()======================
Move tray : 3号盘子 from 2号塔 to 3号塔
2号塔:[],1号塔:[2号盘子,1号盘子],3号塔:[4号盘子,3号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 1号塔 to 2号塔
1号塔:[2号盘子],3号塔:[4号盘子,3号盘子],2号塔:[1号盘子]
=====================Hanoi.move()======================
Move tray : 2号盘子 from 1号塔 to 3号塔
1号塔:[],2号塔:[1号盘子],3号塔:[4号盘子,3号盘子,2号盘子]
=====================Hanoi.move()======================
Move tray : 1号盘子 from 2号塔 to 3号塔
2号塔:[],1号塔:[],3号塔:[4号盘子,3号盘子,2号盘子,1号盘子]
或者:
- import java.util.Stack;
- public class Demo {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- int n=3;
- int disks=5;
- Tower[] towers= new Tower[ n];
- for( int i=0; i< n; i++){
- towers[ i]= new Tower( i);
- }
- for( int i= disks; i>=0; i--){
- towers[0].add( i);
- }
- towers[0].moveDisks( disks, towers[2], towers[1]);
- }
- }
- class Tower{
- public Stack<Integer> disks;
- public int index;
- public Tower(int index){
- disks= new Stack<Integer>();
- this. index= index;
- }
- public int getIndex(){
- return this. index;
- }
- public void add(int d){
- if(! disks.isEmpty()&& disks.peek()<= d)
- System. out.println( "Error placing disk"+d);
- else
- disks.push( d);
- }
- //将orgin顶端的盘子移到destination
- public void movetoTop(Tower t){
- int top= disks.pop();
- t.add( top);
- System. out.println( "Move disk "+ top+ " from "+this.getIndex()+" to "+t.getIndex());
- }
- public void moveDisks( int n,Tower destination,Tower buffer){
- if( n>0){
- //将顶端n-1个盘子从origin移到buffer
- moveDisks( n-1, buffer, destination);
- this.movetoTop( destination);
- //将顶部n-1个盘子从buffer移到destination,将origin用作缓冲区
- buffer.moveDisks( n-1, destination, this);
- }
- }
- }
来源:oschina
链接:https://my.oschina.net/u/2822116/blog/789451