学习数据结构和算法的日常Demo
骑士周游算法介绍
算法分析
代码实现
public class HorseChessBoard {
private static int X = 8; // 棋盘的列数(左右)
private static int Y = 8; // 行数(上下)
// 创建数组,标记棋盘的各个位置是否被访问过
private static boolean visited[] = new boolean[X * Y]; // 初始值都是false
// 使用属性标记是否棋盘的所有位置都被访问过
private static boolean finished; // 为true则访问
public static void main(String args[]) {
int row = 1; // 初始位置的行,从1开始编号
int col = 1; // 初始位置的列,1开始编号
// 创建棋盘
long start = System.currentTimeMillis();
int chessboard[][] = new int[X][Y];
travel(chessboard, row - 1, col - 1, 1);
for (int[] ints : chessboard) {
for (int i : ints) {
System.out.printf("%5d", i);
}
System.out.println();
}
long end = System.currentTimeMillis();
System.out.println("耗时/秒:" + (end - start) / 1000);
System.out.println("耗时/毫秒:" + (end - start));
}
/**
* @param chessboard
* @param row 马当前的行
* @param col 马当前的列
* step 第几步,初始位置第一步
*/
public static void travel(int[][] chessboard, int row, int col, int step) {
chessboard[row][col] = step;
//row = 4,x=8 col = 4
// 36
visited[row * X + col] = true; // 标记该位置已访问
// 获取当前位置可以走的下一个位置的集合
ArrayList<Point> ps = next(new Point(col, row));
// 对ps排序,排序规则是对ps的所有points对象的下一步位置数目,进行非递减排序
// sort(ps);
// 遍历ps
while (!ps.isEmpty()) {
// 取出一个可以走的位置
Point point = ps.remove(0);
// 判断该点是否已经访问过
// 说明没有访问过
if (!visited[point.y * X + point.x]) {
travel(chessboard, point.y, point.x, step + 1);
}
}
// 判断马儿是否完成了任务,使用step和应该走的步数毕竟
// 如果没有达到数量,表示没有完成任务,将棋盘置0
// 1.目前为止,仍未走完
// 2.棋盘处于回溯过程
if (step < X * Y && !finished) {
chessboard[row][col] = 0;
visited[row * X + col] = false;
} else {
finished = true;
}
}
/**
* 根据当前位置,计算马还能走哪些位置,最多八个位置
*
* @param curPoint
* @return
*/
public static ArrayList<Point> next(Point curPoint) {
ArrayList<Point> points = new ArrayList<>();
// 创建一个Point
Point point = new Point();
// 判断马是否可以走5位置
if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y - 1) >= 0) {
points.add(new Point(point));
}
// 判断马是否可以走6位置
if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y - 2) >= 0) {
points.add(new Point(point));
}
// 判断马是否可以走7位置
if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y - 2) >= 0) {
points.add(new Point(point));
}
// 判断马是否可以走0位置
if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y - 1) >= 0) {
points.add(new Point(point));
}
// 判断马是否可以走1位置
if ((point.x = curPoint.x + 2) < X && (point.y = curPoint.y + 1) < Y) {
points.add(new Point(point));
}
// 判断马是否可以走2位置
if ((point.x = curPoint.x + 1) < X && (point.y = curPoint.y + 2) < Y) {
points.add(new Point(point));
}
// 判断马是否可以走3位置
if ((point.x = curPoint.x - 1) >= 0 && (point.y = curPoint.y + 2) < Y) {
points.add(new Point(point));
}
// 判断马是否可以走4位置
if ((point.x = curPoint.x - 2) >= 0 && (point.y = curPoint.y + 1) < Y) {
points.add(new Point(point));
}
return points;
}
}
采用贪心算法进行优化
// 根据当前这一步的所有下一步的选择位置,进行非递归操作
public static void sort(ArrayList<Point> ps) {
ps.sort((o1, o2) -> {
// 获取到o1点的下一步的所有位置个数
int count1 = next(o1).size();
int count2 = next(o2).size();
return count1 - count2;
});
}