1.6用栈来求解三柱汉诺塔问题

版权声明:本文采用 知识共享署名4.0 国际许可协议进行许可。 https://blog.csdn.net/youmian6868/article/details/89139560
题目

求三柱汉诺塔有N层的时候,打印最优移动过程和最优移动总步数。且限制不能从最左侧的塔直接移动到最右侧,也不能从最右侧直接移动到最左侧,而是必须经过中间。

思路

修改后的汉诺塔问题实际动作只有4个:“左”到“中”,“中”到“左”,“中”到“右”,“右”到“中”。

一个动作能发生的先决条件有两个:

  1. 不违反小压大原则:from栈弹出的元素num如果想压入to栈中,那么num的值必须小于当前to栈的栈顶。
  2. 相邻不可逆原则:如果想走出最少步数,那么任何两个相邻的动作都不是互为逆过程的。

根据以上两个原则,可以推导出两个结论:

  1. 第一个动作一定是L->M。
  2. 在走出最少步数过程中的任何时刻,四个动作只有一个动作不违反以上两个原则,另外三个动作一定都会违反。
代码实现
//三柱汉诺塔,且规定每次只能在相邻柱之间移动
public class HanoiProblem {
    public enum Action {
        No, LToM, MToL, MToR, RToM
    }

    public int hanoiProblem(int num, String left, String mid, String right) {
        Stack<Integer> lS = new Stack<>();
        Stack<Integer> mS = new Stack<>();
        Stack<Integer> rS = new Stack<>();

        lS.push(Integer.MAX_VALUE);
        mS.push(Integer.MAX_VALUE);
        rS.push(Integer.MAX_VALUE);
        for (int i = num; i > 0; i--) {
            lS.push(i);
        }
        Action[] record = {Action.No};
        int step = 0;

        while (rS.size() != num + 1) {
        step += fStackTotStack(record, Action.MToL, Action.LToM, lS, mS, left, mid);
        step += fStackTotStack(record, Action.LToM, Action.MToL, mS, lS, mid, left);
        step += fStackTotStack(record, Action.RToM, Action.MToR, mS, rS, mid, right);
        step += fStackTotStack(record, Action.MToR, Action.RToM, rS, mS, right, mid);
        }

        return step;
    }

    public static int fStackTotStack(Action[] record, Action preNoAct, Action nowAct, Stack<Integer> fStack, Stack<Integer> tStack, String from, String to) {
        if (record[0] != preNoAct && fStack.peek() < tStack.peek()) {
            tStack.push(fStack.pop());
            System.out.println("Move " + tStack.peek() + " from " + from + " to " + to);
            record[0] = nowAct;

            return 1;
        }

        return 0;
    }

    public static void main(String[] args) {
        HanoiProblem hanoi = new HanoiProblem();

        System.out.println("求解三层汉诺塔最小步数:" + hanoi.hanoiProblem(3, "left", "mid", "right"));
    }
}

猜你喜欢

转载自blog.csdn.net/youmian6868/article/details/89139560