日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

栈和队列----用栈求解汉诺塔问题

發布時間:2024/4/17 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 栈和队列----用栈求解汉诺塔问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

用棧求解漢諾塔問題

  

  漢諾塔問題比較經典,現在修改一下漢諾塔游戲的規則:規定不能直接從左移動到右,也不能直接從右移動到左,必須經過中柱,求解當塔有N層的時候,打印最優移動過程和最優移動總步數。

  可以采用兩個方法解決。方法一采用遞歸的方法;方法二采用非遞歸的方法,用棧來模擬漢諾塔的三個塔。

?

package com.test;import java.util.Stack;/*** Created by Demrystv.*/ public class SolveHanoiWithStack {//遞歸的方法,左->中,右->中,中->左,中->右,都是需要三個步驟,左->右,右->左,都是需要五個步驟public int hanoiProblem1(int num, String left, String mid, String right){if (num < 1){return 0;}return process(num, left, mid, right, left, right);}private int process(int num, String left, String mid, String right, String from, String to){if (num==1){if (from.equals(mid) || to.equals(mid)){System.out.println("Move 1 from " + from + " to " + to);return 1;}else {System.out.println("Move 1 from " + from + " to " + mid);System.out.println("Move 1 from " + mid + " to " + to);return 2;}}if (from.equals(mid) || to.equals(mid)){String another = (from.equals(left)) || (to.equals(left)) ? right : left;int part1 = process(num-1, left, mid, right, from, another);int part2 = 1;System.out.println("Move " + num + " from " + from + " to " + another);int part3 = process(num-1, left, mid, right, another, to);return part1 + part2 + part3;}else {int part1 = process(num-1, left, mid, right, from, to);int part2 = 1;System.out.println("Move " + num + " from " + from + " to " + mid);int part3 = process(num-1, left, mid, right, to, from);int part4 = 1;System.out.println("Move " + num + " from " + mid + " to " + to);int part5 = process(num-1, left, mid, right, from, to);return part1 + part2 + part3 + part4 + part5;}}//非遞歸方法用到的枚舉類,因為不能直接從左到右,所以就只有四個動作public enum Action{No, LToM, MToL, MToR, RToM}//非遞歸的方法,用棧來模擬整個過程//核心思想:// 需要遵守兩個原則,// 一個是不能違反小壓大的原則,from棧彈出的元素num想壓入到to棧中,那么num的值必須小于等于當前to棧的棧頂// 另一個是相鄰不可逆原則,即不能上一步是左到中,下一步是中到左,不滿足最小步數// 由這兩個原則可以推出非遞歸方法的兩個結論:// 1.游戲的第一個動作一定是 左 到 中// 2.四個動作中只有一個動作和相鄰不可逆原則,其余三個一定都會違反,可以證明// 因此,每一步只有一個動作達標,那么只要每一步都根據這兩個原則考察所有的動作即可,哪個滿足就進行哪個動作,按照順序走下來即可。public int hanoiProblem2(int num, String left, String mid, String right){Stack<Integer> lS = new Stack<Integer>();Stack<Integer> mS = new Stack<Integer>();Stack<Integer> rS = new Stack<Integer>();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 += fStackToStack(record, Action.MToL, Action.LToM, lS, mS, left, mid);step += fStackToStack(record, Action.LToM, Action.MToL, mS, lS, mid, left);step += fStackToStack(record, Action.RToM, Action.MToR, mS, rS, mid, right);step += fStackToStack(record, Action.MToR, Action.RToM, rS, mS, right, mid);}return step;}private int fStackToStack(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;} }

?

轉載于:https://www.cnblogs.com/Demrystv/p/9292776.html

總結

以上是生活随笔為你收集整理的栈和队列----用栈求解汉诺塔问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。