Cracking the coding interview--Q3.4

题目

原文:

In the classic problem of the Towers of Hanoi, you have 3 rods and N disks of different sizes which can slide onto any tower. The puzzle starts with disks sorted in ascending order of size from top to bottom (e.g., each disk sits on top of an even larger one). You have the following constraints:
(A) Only one disk can be moved at a time.
(B) A disk is slid off the top of one rod onto the next rod.
(C) A disk can only be placed on top of a larger disk.
Write a program to move the disks from the first rod to the last using Stacks.

译文:

经典的汉诺塔问题,有3根柱子,柱子上串有N个尺寸不同的碟子。汉诺塔问题的起始状态为,所有的碟子都从小到大的穿在柱子上(下面的碟子最大)。在满足下面三个限制:(A) 每次只能移动一个碟子;(B) 只有每根柱子顶端的碟子才能移动;(C)任何碟子只能放在比它大的碟子上。写一段程序(要求使用堆栈),将第一个根柱子上所有的碟子移动到移到最后一根柱子上。

解答

原书解答

首先我们考虑解题的算法:将N个碟子从第一根柱子移到最后一根柱子。我们先从最简单的情况开始。如果只有一个碟子,那么直接将它移到最后的柱子。那两个碟子呢?
(1)先将第一个碟子从第一根柱子移到第二根
(2)将第二个碟子从第一根柱子上移动到第三根
(3)再将第二根柱子上的碟子移动到第三根上,完成!
那三个碟子呢?
(1)采用两个碟子移动的方法,讲上两个碟子移动到第二根柱子上
(2)将第三个碟子移动到第三根柱子
(3)在采用运来的方法将第二根柱子上的两个碟子移动到第三根柱子。
很明显采用递归算法就能解决本题:

import java.util.*;

class Q3_4{
	public static void main(String[] args){
		int n = 5;
		Tower[] towers = new Tower[n];
		for (int i = 0; i < 3; i++) 
			towers[i] = new Tower(i);
		for (int i = n - 1; i >= 0; i--) 
			towers[0].add(i);
		towers[0].moveDisks(n, towers[2], towers[1]);
	}
}

class Tower
{
    private Stack<Integer> disks;
    private int index;
    public Tower(int i)
    {
        disks = new Stack<Integer>();
        index = i;
    }

    public int index()
    {
        return index;
    }

    public void add(int d)
    {
        if (!disks.isEmpty() && disks.peek() <= d)
        {
            System.out.println("Error placing disk" + d);
        }
        else
        {
            disks.push(d);
        }
    }

    public void moveTopTo(Tower t)
    {
        int top = disks.pop();
        t.add(top);
        System.out.println("Move disk " + top + " from " + index() + " to "+ t.index());
    }

    public void print()
    {
        System.out.println("Contents of Tower" + index());
        for (int i = disks.size() - 1; i >= 0; i--)
        {
            System.out.println(""+ disks.get(i));
        }
    }

    public void moveDisks(int n, Tower destination, Tower buffer)
    {
        if (n > 0)
        {
            moveDisks(n - 1, buffer, destination);
            moveTopTo(destination);
            buffer.moveDisks(n - 1, destination, this);
        }
    }
}

---EOF---

你可能感兴趣的:(Cracking the coding interview--Q3.4)