1. 应用的知识点java的二维数组;int[][] chessBorad=int [X][Y];
2. 用了一维数组boolean[] visited=new boolean[X*Y];
3. Point p;p.x,p.y,点的坐标的这个类
在一个8*8的方格中,要求从任何的起点出发尽可能多的不重复的方格?怎么可以把方格走完?
实现思路:
代码实现:
注意的地方:要实现这个算法需要了解Point类java.awt包中,需要把这个类里面的点存入ArrayList集合中
travelChessBorad();方法用于用合适的点遍历棋盘。
ArrayList next(Point currrentPoint)方法:仅仅表示符合要求的点,然后travelChessBorad()中调用 这个方法就可以实现找出所有的棋盘中符合要求 的点。(后期还会对这个进行优化)
package com.demo.sort;
import java.awt.*;
import java.util.ArrayList;
import java.util.Comparator;
class HorseChessBoard {
private static int X;//棋盘的列
private static int Y;//棋盘的行
// 用一个数组来表示这个棋盘的位置是否被访问过
private static boolean visited[];
// 使用一个属性来表示棋盘是否所有的位置都被访问
private static boolean finished;//所有的boolean默认为false
static int count = 0;//用来统计次数的
/**
* @param args
*/
// 这个是一个判断条件的函数如果符合条件就添加进来
public static void main(String[] args) {
X = 6;
Y = 6;
int row = 1;//马儿的初始位置从1开始
int column = 1;//马儿的初始位置从1开始编号
visited=new boolean[X*Y];//初始值都为false
int[][] chessborad = new int[X][Y];
// 测试一下耗时
long start = System.currentTimeMillis();
travelChessBorad(chessborad, 1, 2, 1);
//打印出来毫秒
long end = System.currentTimeMillis();
System.out.println((end - start));
// 输出棋盘
for (int[] rows : chessborad) {
System.out.println();
for (int step : rows) {
System.out.print(step + "\t");
}
}
System.out.println("循环次数"+count);
}
// 遍历棋盘用来找符合的情况
public static void travelChessBorad(int[][] chessborad, int row, int column, int step) {
//1.走完棋盘
chessborad[row][column] = step;//把每一个方格当成下一个数字
// row=4 X=8,column=4
// visited标记该位置已经被访问
visited[row * X + column] = true;//表示马儿从该点开始出发
// 获取当前位置可以走的下一个集合 把棋盘传入我们需要的函数,用来判断是否符合条件
ArrayList<Point> ps = next(new Point(column, row));
// 对他的下一步的次数进行非递减排序
sort(ps);
// 遍历ps
while (!ps.isEmpty()) {
Point p = ps.remove(0);//可以走的位置的值全部为0,走了之后visited[row][column]=true;
// 判断该点是否被访问过
if (!visited[p.y * X + p.x]) {//说明还没有被访问
// 访问下一个点
travelChessBorad(chessborad, p.y, p.x, step + 1);
count++;
}
}
//2.没有走完棋盘
// 判断马儿是否完成了任务,使用step和应该步数比较
// step<X*Y是否走完有两种情况:1.棋盘没有走完 2. 正处在一个回溯的过程
if (step < X * Y && !finished) {
chessborad[row][column] = 0;
visited[row * X + column] = false;
} else {
finished = true;
}
}
//当前的这个点由自己来决定,只要符合要求即可。
public static ArrayList<Point> next(Point currentPoint) {
// 创建一个ArrayList
ArrayList<Point> ps=new ArrayList<>();
//创建一个Point
Point p1 = new Point();
// 表示马儿可以走,图中的数表示最多的马可以走的个数,0,1,2,3,4,5,6,7
//表示马儿可以走5这个位置
// (总共八个数可以走只要符合稍作就可以加入到这个数组中)
if ((p1.x = currentPoint.x - 2) >= 0 && (p1.y = currentPoint.y - 1) >= 0) {
ps.add(new Point(p1));//符合要求把这个点加入到数组中
}
// 0
if ((p1.x = currentPoint.x + 2) <X && (p1.y = currentPoint.y - 1) >= 0) {
ps.add(new Point(p1));//符合要求把这个点加入到数组中
}
// 表示走6这个位置,如果x,y不出边界就可以
if ((p1.x = currentPoint.x - 1) >= 0 && (p1.y = currentPoint.y - 2) >= 0) {
ps.add(new Point(p1));
}
// 表示走7这个位置
if ((p1.x = currentPoint.x + 1) < X && (p1.y = currentPoint.y - 2) >= 0) {
ps.add(new Point(p1));
}
// 1这个位置
if ((p1.x = currentPoint.x + 2) < X && (p1.y = currentPoint.y +1) <Y) {
ps.add(new Point(p1));//符合要求把这个点加入到数组中
}
// 4
if ((p1.x = currentPoint.x -2) >=0 && (p1.y = currentPoint.y +1) <Y) {
ps.add(new Point(p1));//符合要求把这个点加入到数组中
}
// 3
if((p1.x=currentPoint.x-1)>=0&&(p1.y=currentPoint.y+2)<Y){
ps.add(new Point(p1));
}
// 2
if((p1.x=currentPoint.x+1)<X &&(p1.y=currentPoint.y+2)<Y){
ps.add(new Point(p1));
}
return ps;//返回这个点
}
// 减少回溯的次数
// 对这个算法的回溯的时候进行 非递减排序(1,2,2,3,3,4,5,5)可以有重复的数字
public static void sort(ArrayList<Point> ps){
ps.sort(new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
// 获取o1的下一步的所有的位置个数
int count1=next(o1).size();
int count2=next(o2).size();
if (count1<count2){
return -1;
}else if(count1==count2){
return 0;
}else {
return -1;
}
}
});
}
}