public class HorseChessBox { //static 常量棋盘行数 static int x=8; //常量棋盘列数 static int y=8; //用来遍历输出比较次数 static int count = 0; // 创建一个数组 标记各个位置是否被访问过 private static boolean[] visited; // 使用一个属性 标记棋盘的所有位置是否被 访问过 private static boolean finished; public static void main(String[] args) { int row = 2; // 马儿初始位置的行 int clo = 4; // 马儿初始位置的列 //定义棋盘 int [][] chessboard = new int[x][y]; //初始访问数组都是false visited = new boolean[x * y]; // 测试一下花费时间 long start = System.currentTimeMillis(); System.out.println("开始时间 " + start); traversalChessBoard(chessboard, row - 1, clo - 1, 1); long end = System.currentTimeMillis(); System.out.println("结束时间 " + end); System.out.println("功共耗时 " + (end - start) + "毫秒"); System.out.println("输出结果"); for (int[] arr : chessboard) { System.out.println(Arrays.toString(arr)); } } /** * 完成马踏棋盘算法 * @param chessboard 棋盘 * @param row 马儿当前位置的行 * @param col 马儿当前位置的列 * @param step 表示马儿走的是第几步 初始位置是第一步 */ public static void traversalChessBoard(int[][] chessboard, int row, int col, int step) { System.out.println("第" + (++count) + "次比较"); //先把第一步定义在棋盘上 chessboard[row][col] = step; // 若第四行 row=4 x为 8 clo = 4 4 * 8 = 4 = 36 (从1开始 所以 37 -1 = 36) 看图!!! visited[row * x + col] = true; // 标记已访问 // 获取下一节点的位置的集合 ArrayList<Point> ps = next(new Point(col, row)); //在进行遍历之前,先对next数组进行贪心算法的优化 sort(ps); //使用while循环判断是否为空,因为每次循环进去都需要从arraylist中remove出一个节点来进行判断 while (!ps.isEmpty()) { //remove第一个节点 Point p = ps.remove(0); //判断节点时候已经被访问,如果没有被访问过,则进行遍历 if (!visited[p.y * x + p.x]) { // 没有访问过 traversalChessBoard(chessboard, p.y, p.x, step + 1); } } //这里就是路走不通的时候进行回溯,这里的回溯其实是在内层循环时的回溯 //也就是比如当我找第一个节点的时候,回递归进入下一个节点找它的下一个节点,如果下一个节点的下一个节点集合都已经被访问或者是不存在,则进行回溯,回到第一个点找下一个节点的时候,去找另一个下节点 if (step < x * y && !finished) { chessboard[row][col] = 0; visited[row * x + col] = false; }else { finished = true;//如果全部都已经被访问了,则将finished设true } } //判断当前节点下次可以走的节点的集合 public static ArrayList<Point> next(Point curPoint){ // 创建一个ArrayList ArrayList<Point> ps = new ArrayList<>(); /// 创建一个point对象 Point p1 = new Point(); //走图中5的位置 if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y - 1) >= 0) { ps.add(new Point(p1)); } //图中6的方向 if ((p1.x=curPoint.x-1)>=0 &&(p1.y=curPoint.y-2)>=0){ ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'7'的位置 if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y - 2) >=0) { ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'0'的位置 if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y - 1) >=0) { ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'1'的位置 if ((p1.x = curPoint.x + 2) < x && (p1.y = curPoint.y + 1) < y) { ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'2'的位置 if ((p1.x = curPoint.x + 1) < x && (p1.y = curPoint.y + 2) < y) { ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'3'的位置 if ((p1.x = curPoint.x - 1) >= 0 && (p1.y = curPoint.y + 2) < y) { ps.add(new Point(p1)); } // 判断可不可以走可以走 图中'4'的位置 if ((p1.x = curPoint.x - 2) >= 0 && (p1.y = curPoint.y + 1) < y) { ps.add(new Point(p1)); } return ps; } //使用贪心算法优化马踏棋盘 public static void sort(ArrayList<Point> ps){ ps.sort(new Comparator<Point>() { @Override public int compare(Point o1, Point o2) { //前者比较小,则返回负数 if (next(o1).size()<next(o2).size()){ return -1; //前者比较大则返回正数 } else if (next(o1).size()>next(o2).size()){ return 1; //两个一样大,则返回0 } else { return 0; } } }); } }
优化后效率: