河内代码塔的bug

时间:2015-02-26 03:33:30

标签: java algorithm recursion towers-of-hanoi

在编码河内塔的递归解决方案时,我的代码适用于1,2和3张光盘,但之后却没有。 无法弄清楚我做错了什么。

package recursion;

import java.util.List;

import org.springframework.util.Assert;

import com.google.common.collect.Lists;
import com.google.common.collect.Ordering;

public class Hanoi {

    private static List<Integer> reference = Lists.newArrayList(4, 3, 2, 1);

    private static List<Integer> aList = Lists.newArrayList(reference);
    private static List<Integer> bList = Lists.newArrayListWithCapacity(aList.size() - 1);
    private static List<Integer> cList = Lists.newArrayListWithCapacity(aList.size());

    public static void main(String[] args) {

        hanoi(aList, bList, cList);
        System.out.println(cList);
        Assert.isTrue(cList.equals(reference));
        Assert.isTrue(aList.size() == 0);
        Assert.isTrue(bList.size() == 0);
        System.out.println("done");

    }

    private static void hanoi(List<Integer> aList, List<Integer> bList, List<Integer> cList) {
        if (aList.size() == 1) {
            cList.add(aList.remove(0));
            return;
        }
        hanoi(aList.subList(1, aList.size()), cList, bList);
        print();
        hanoi(aList.subList(0, 1), null, cList);
        print();
        hanoi(bList, aList, cList);
        print();
        System.out.println("=======================================");
    }

    private static void print() {
        System.out.println(aList);
        System.out.println(bList);
        System.out.println(cList);
        Assert.isTrue(Ordering.natural().reverse().isOrdered(aList));
        Assert.isTrue(Ordering.natural().reverse().isOrdered(bList));
        Assert.isTrue(Ordering.natural().reverse().isOrdered(cList));
        System.out.println("******************************************");
    }
}

1 个答案:

答案 0 :(得分:1)

您的算法基于这样的假设:河内的塔总是移动所有切片,除了第一步(和最后一步)中的切片。

这是假设是错误的。子问题转移了较小的塔。

为你的hanoi方法添加一个param大小。必须调整所有三个步骤:

  • 步骤1和3只应移动size-1
  • 第2步不应该移动第一个切片,而应该移动最后一个切片(最上部)