🎯
【Java】ハノイの塔1
ハノイの塔とは
ハノイの塔とは、19世紀にフランスの数学者エドゥアール・リュカによって提唱されました。
ハノイの塔は、3本の杭とその中に円盤が積まれた状態で始まります。最初は、すべての円盤が1つの杭に大きい順に積まれています。この状態から、下記のルールに従ってすべての円盤を別の杭に移動させることが目的です。
- 1度に1つの円盤のみ移動できます。
- 大きな円盤を小さな円盤の上に置くことはできません。
ハノイの塔1のコード
まず、ここでは、下記のハノイの塔の最初の状態を出力できるコードを紹介します。
以下、ハノイの塔の最初の状態を出力できるコード。
import java.util.*;
public class Main {
/*
3本の杭をまとめるList。 -> 外側のリスト:piles
杭の状態を表すLinkedList。円盤を格納。 -> 内側のリスト:名前なし
円盤の大きさを整数で表す。 -> 内側のリストの要素:名前なし
*/
// 二重リストpilesを宣言
static List <LinkedList<Integer>> piles;
// ハノイの塔を初期化するメソッド
static void initialize(int n) {
// 3本の杭をまとめるListの初期化
piles = new LinkedList<>();
// 杭の状態を表すLinkedListを3つ生成し、3本の杭を作る。
for (int i = 0; i < 3; i++) {
piles.add(new LinkedList<>());
}
// 0番目の杭に、n枚の円盤を追加
for (int i = n; i >= 1; i--) {
piles.get(0).add(i);
}
}
// ハノイの塔を表示するメソッド
static void printPiles() {
System.out.println("--"); // 区切り線を表示
for (int i = 0; i < 3; i++) {
System.out.print(i + ":"); // 杭の番号を表示
for (int disk : piles.get(i)) {
System.out.print(" " + disk); // 円盤の大きさを表示
}
System.out.println(); // 改行して次の杭に移る
}
}
public static void main(String args[] ) {
int n = 3; // 円盤の数を宣言
System.out.println(n); // 円盤の数を表示
initialize(n); // ハノイの塔を初期化
printPiles(); // ハノイの塔の最初の状態を表示
// 0: 3 2 1
// 1:
// 2:
}
}
ハノイの塔1のコードの解説
二重リストの宣言
static List <LinkedList<Integer>> piles;
piles
という変数は、List
型のオブジェクトであり、その要素としてLinkedList<Integer>
オブジェクトを持ちます。
さらに、LinkedList<Integer>
オブジェクトは、Integer
型の要素を持ちます。
繰り返しになりますが、二重リストであるpiles
は、上記のように、
外側のList
は、要素としてLinkedList
を持ち、
内側のLinkedList
は、要素としてInteger
を持ちます。
ハノイの塔を初期化するメソッド
static void initialize(int n) {
// 3本の杭をまとめるListの初期化
piles = new LinkedList<>();
// 杭の状態を表すLinkedListを3つ生成し、3本の杭を作る。
for (int i = 0; i < 3; i++) {
piles.add(new LinkedList<>());
}
// 0番の杭に、n枚の円盤を追加
for (int i = n; i >= 1; i--) {
piles.get(0).add(i); // 最初の杭に円盤を追加する
}
}
- 仮引数
n
を受け取るinitialize
メソッドを定義して、 - 変数
piles
に外側のList
のインスタンスを代入します。
piles
の出力結果は[]
となり、List
が1つ作成されました。
- 3回の反復処理を行うfor文を定義して、
- 変数
piles
(=List
のインスタンス)に3つのLinkedList
のインスタンスを生成します。
piles
の出力結果は[[], [], []]
となり、1つのListの中に3つのLinkedList
が作成されました。
- 後述しますが
n
は3
なので、i = 3 → 2 → 1
と繰り返す、for文を定義して、 - 0番目の
LinkedList
にi
を追加します。
piles
の出力結果は[[3, 2, 1], [], []]
となります。
ハノイの塔を表示するメソッド
static void printPiles() {
System.out.println("--"); // 区切り線を表示
for (int i = 0; i < 3; i++) {
System.out.print(i + ":"); // 杭の番号を表示
for (int disk : piles.get(i)) {
System.out.print(" " + disk); // 円盤の大きさを表示
}
System.out.println(); // 改行して次の杭に移る
}
}
-
printPiles
メソッドを定義して、 - 区切り線
--
を出力します。 - for文を定義して、
- 0番目の杭を表す
0:
を出力します。以降、順番に1: → 2:
と出力します。 - for文の中に拡張for文を定義して、0番目の杭の
LinkedList
の要素を取り出し、変数disk
に代入します。 - 半角スペースと0番目の杭の円盤
3 → 2 → 1
を出力します。 - 改行を出力して、次の1番目の杭に移るために
3.for文
に戻ります。
mainメソッド
public static void main(String args[] ) {
int n = 3; // 円盤の数を宣言
System.out.println(n); // 円盤の数を表示
initialize(n); // ハノイの塔を初期化
printPiles(); // ハノイの塔の最初の状態を表示
}
mainメソッドで、
- 変数nに3を代入します。これは円盤の枚数が3であることを宣言しています。
- 変数nを出力します。これは円盤の枚数である
3
を出力します。 - 3が代入された実引数nを渡すinitializeメソッドを呼び出します。
- printPilesを呼び出します。これにより下記の通り出力されます。
0: 3 2 1
1:
2:
Discussion