算法1:
题目:汉诺塔(修改版,每一步必须经过中间,比如:想要左->右,要左->中,中->右来实现),通过递归实现
{代码}
/**
* 汉诺塔(修改版,每一步必须经过中间,比如:想要左->右,要左->中,中->右来实现),通过递归实现
*/
public class Hanoi {
public int hanoiProbleml(int num,String left,String mid,String right){
if(num<1){
return 0;
}
return process(num,left,mid,right,left,right);
}
/**
*递归方法的实现(个人感觉有点难推导)
* @param num 总共塔的层数
* @param left
* @param mid
* @param right
* @param from 初值为left
* @param to 初值为right
* @return 步数
*/
public int process(int num,String left,String mid,String right,String from,String to){
if(num == 1){//如果只有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 "+to);
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 static void main(String[] args){
Hanoi hanoi = new Hanoi();
int step = hanoi.hanoiProbleml(3,"左","中","右");
System.out.println("总共用了"+step+"步");
}
}
算法2:
题目:汉诺塔(修改版,每一步必须经过中间,比如:想要左->右,要左->中,中->右来实现),通过非递归实现
{代码}
import java.util.Stack;
/**
* 汉诺塔(修改版,每一步必须经过中间,比如:想要左->右,要左->中,中->右来实现),通过非递归实现
*/
public class Hanoi2 {
public static int hanoiProblem2(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);//最大值:2147483647(2的7次方-1)
mS.push(Integer.MAX_VALUE);
rS.push(Integer.MAX_VALUE);
for(int i = num;i>0;i--){//将数字(最小数字在栈顶)压入左栈[1,2,3]
lS.push(i);
}
//调用枚举
Action[] record = {Action.No};
int step = 0;
//size();stack类从vector继承的方法;返回此向量中的组件数
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,left,mid);
}
return step;
}
public static int fStackToStack(Action[] record,Action preNoAet,Action nowAct,Stack<Integer> fStack,Stack<Integer> tStack,String from,String to){
if(record[0] != preNoAet && fStack.peek()<tStack.peek()){//发生移动且必须小的数字往大的数字上移动
tStack.push(fStack.pop());//fStack 移动到 tStack 且删掉from的栈顶元素
System.out.println("Move "+ tStack.peek() + " from "+from + " to "+to);
record[0] = nowAct;
return 1;
}
return 0;
}
public static void main(String[] args){
int step = hanoiProblem2(3,"左","中","右");
System.out.println("总共需要"+step+"步");
}
}
/**
* 枚举,不移动,左移中,中移左,中移右,右移中
*/
enum Action{
No,LToM,MToL,MToR,RToM
}