漢諾塔
有三根相鄰的柱子,標號為A,B,C,A柱子上從下到上按金字塔狀疊放着n個不同大小的圓盤,
要把所有盤子一個一個移動到柱子B上,並且每次移動同一根柱子上都不能出現大盤子在小
盤子上方。
--如果朋友您想轉載本文章請注明轉載地址"http://www.cnblogs.com/XHJT/p/3878076.html "謝謝--
問題:
1.如何移動;
2.n個盤子移動多少次(count)?
解決問題1:
為了將第n個盤子從A移動到C,就得先將第n個盤子上面的第n-1盤子移動到B上;
同樣的,要想將B上的第n-1個盤子移動到C上,就得先將第n-2個盤子移動到A上。
解決問題2:
當n = 1 時,count = 1;
當n = 2 時,count = 3;
當n = 3 時,count = 7;
當n = 4 時,count = 15;
…………
根據以上可得表達式:
count(1) = 1
count(n) = 2*count(n)+1 (n>1)
即n個盤子移動的次數表達式為:
count(n) = 2^n - 1 (n>0)
用代碼實現為:
package com.xhj.data;
import java.util.Scanner;
/**
* 遞歸算法實現漢諾塔
*
* @author XIEHEJUN
*
*/
public class HanoiTower {
/**
* 定義移動次數
*/
private static int count;
/**
* 設置移動次數的起始值
* @param count
*/
public static void setCount() {
HanoiTower.count = 1;
}
/**
* 獲取移動次數
*
* @return
*/
public static int getCount() {
return count-1;
}
/**
* 移動遞歸
*
* @param num
* 盤子數
* @param from
* 柱子A
* @param inner
* 柱子B
* @param to
* 柱子C
*/
public static void moveDish(int num, char from, char inner, char to) {
if (num == 1) {
System.out.println("\t\t**\t"+count++ + " " + num + "號盤子從" + from + "移動到" + to);
} else {
moveDish(num - 1, from, inner, to);
System.out.println("\t\t**\t"+count++ + " " + num + "號盤子從" + from + "移動到" + to);
moveDish(num - 1, inner, from, to);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
for (;;) {
System.out.print("請輸入盤子的個數:");
int n = sc.nextInt();
System.out.println("\t\t**********************************");
System.out.println("\t\t**\t移動步驟為:");
setCount();
moveDish(n, 'A', 'B', 'C');
System.out.println("\t\t**\t一共移動的步數為:" + getCount());
System.out.println("\t\t**********************************");
}
} catch (Exception e) {
System.out.println("輸入數據不正確,請輸入整數");
main(null);
}
}
}
