Cracking the coding interview--Q3.4

本文介绍经典的汉诺塔问题,并提供一种基于递归算法的解决方案。使用Java实现了一个程序,该程序通过堆栈操作将不同大小的碟子从一根柱子移动到另一根柱子,同时遵循汉诺塔问题的规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

原文:

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---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值