8数码问题(1)
使用dfs, 果然效率很低,生成的遍历树很deep啊,所以有时间实现bfs和a*的,使用java编写。。。
贴上代码
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Stack; /** * * @author earthgee * *八数码(1),使用dfs */ public class EightNum { public static Stack<List<Integer>> path=new Stack<List<Integer>>(); //记录路径 public static HashSet<List<Integer>> old=new HashSet<List<Integer>>(); //记录访问过的路径,用于去重 public static List<Integer> target=new ArrayList<Integer>(); //目标路径 static{ target.add(1); target.add(2); target.add(3); target.add(8); target.add(0); target.add(4); target.add(7); target.add(6); target.add(5); } //0代表空格,此交换函数实现了0的移动 public static List<Integer> swap(List<Integer> num,int num1,int num2) { List<Integer> tmp=new ArrayList<Integer>(); for(int i=0;i<num.size();i++) { if(i==num1) { tmp.add(num.get(num2)); } else if(i==num2) { tmp.add(num.get(num1)); } else { tmp.add(num.get(i)); } } return tmp; } //不解释 public static boolean equalToTarget(List<Integer> num) { for(int i=0;i<9;i++) { if(!(num.get(i)==target.get(i))) { return false; } } return true; } /** * 主函数 * @param num 每一次dfs的路径 * @param k 0的位置 * @return 是否到达目标,用于回溯 */ public static boolean calculate(List<Integer> num,int k) { int tmpp=0; if(equalToTarget(num)) { path.push(num); return true; } old.add(num); //可以看出顺序为:上-左-下-右 if(k-3>=0) { path.push(num); List<Integer> tmp=swap(num,k,k-3); if(old.contains(tmp)) { path.pop(); } else { tmpp=k-3; if(calculate(tmp, tmpp)) { return true; } else { path.pop(); } } } if(k-1>=0&&(k/3==(k-1)/3)) { path.push(num); List<Integer> tmp=swap(num,k,k-1); if(old.contains(tmp)) { path.pop(); } else { tmpp=k-1; if(calculate(tmp, tmpp)) { return true; } else { path.pop(); } } } if(k+3<=8) { path.push(num); List<Integer> tmp=swap(num,k,k+3); if(old.contains(tmp)) { path.pop(); } else { tmpp=k+3; if(calculate(tmp, tmpp)) { return true; } else { path.pop(); } } } if(k+1<=8&&(k/3==(k+1)/3)) { path.push(num); List<Integer> tmp=swap(num,k,k+1); if(old.contains(tmp)) { path.pop(); } else { tmpp=k+1; if(calculate(tmp, tmpp)) { return true; } else { path.pop(); } } } return false; } public static void printList(List<Integer> list) { for(int i=0;i<list.size();i++) { System.out.print(list.get(i)+"-"); } System.out.println(); } //测试实例 public static void main(String[] args) { List<Integer> num=new ArrayList<Integer>(); num.add(1); num.add(0); num.add(3); num.add(7); num.add(2); num.add(4); num.add(6); num.add(8); num.add(5); calculate(num, 1); for(int i=0;i<path.size();i++) { List<Integer> list=path.get(i); printList(list); } } }
测试的深度达到了200多,可怕,这个还是不要用dfs的好