This code is a little improved after reading the A* algorithm in the book Comic Algorithms. The difference is that the original algorithm can only find the smallest path in the map. In addition to finding the smallest path in the map, the improved algorithm can also find the smallest path through penetration. For example, when the path reaches the leftmost, it can find the smallest path from Come out on the right, when you reach the bottom, you can come out from the top, and finally give a demonstration example. It's easy to understand.
import java.util.ArrayList; import java.util.List; import java.util.Scanner; public class AStar { private static ArrayList<Grid> openList = new ArrayList<Grid>(); private static ArrayList<Grid> closeList = new ArrayList<Grid>(); private static int n; private static char[][] map = null; public static Grid aStarSearch(Grid start, Grid end) { ArrayList<Grid> closeList = new ArrayList<Grid>(); openList.add(start); while (openList.size() > 0) { Grid currentGrid = findMinGird(); openList.remove(currentGrid); closeList.add(currentGrid); List<Grid> neighbors = findNeighbors(currentGrid); for (Grid grid : neighbors) { grid.initGrid(currentGrid, end); openList.add(grid); } for (Grid grid : openList){ if ((grid.x == end.x) && (grid.y == end.y)) { return grid; } } } return null; } private static Grid findMinGird() { Grid tempGrid = openList.get(0); for (Grid grid : openList) { if (grid.f < tempGrid.f) { tempGrid = grid; } } return tempGrid; } private static ArrayList<Grid> findNeighbors(Grid grid ) { int max = map.length-1; ArrayList<Grid> neighborList = new ArrayList<Grid>(); int[][] directions = {{-1,0},{0,1},{1,0},{0,-1}}; for(int[] direction:directions) { int neighborX = grid.x+direction[0];if(neighborX<0) {neighborX=max;}else if(neighborX>max) {neighborX=0;} int neighborY = grid.y+direction[1];if(neighborY<0) {neighborY=max;}else if(neighborY>max) {neighborY=0;}; if(isValidGrid(neighborX,neighborY)){ neighborList.add(new Grid(neighborX, neighborY)); } } return neighborList; } private static boolean isValidGrid(int x, int y) { if(map[x][y] == '#'){//Obstacle return false; } if(containGrid(openList, x, y)){ return false; } if(containGrid(closeList, x, y)){ return false; } return true; } private static boolean containGrid(List<Grid> grids, int x, int y) { for (Grid n : grids) { if ((n.x == x) && (n.y == y)) { return true; } } return false; } static class Grid { public int x; public int y; public int f; public int g; public int h; public Grid parent; public Grid(int x, int y) { this.x = x; this.y = y; } public void initGrid(Grid parent, Grid end){ this.parent = parent; if(parent != null){ this.g = parent.g + 1; }else { this.g = 1; } int xL = Math.abs(this.x - end.x) ; int yL = Math.abs(this.y - end.y); int h1 = xL + yL; int h2 = n-xL+yL;int h3 = n-yL + xL; this.h = Math.max(Math.max(h1, h2) , h3); this.f = this.g + this.h; } } public static void main(String[] args) { Scanner sc= new Scanner(System.in); n = sc.nextInt(); map = new char[n][n]; int startX = 0, startY=0, endX=0, endY=0; for(int i=0; i<n; i++) { String input = sc.next(); char[] chars = input.toCharArray(); for(int j=0; j<n; j++) { map[i][j] = chars[j]; if('S' == chars[j]){ startX = i; startY = j; } else if( 'E' == chars[j] ) { endX = i; endY = j; } } } for(int i=0; i<n; i++) { for(int j=0; j<n; j++) { System.out.print(map[i][j]+"\t"); } System.out.println(); } System.out.println(); Grid startGrid = new Grid(startX, startY); Grid endGrid = new Grid(endX, endY); Grid resultGrid = aStarSearch(startGrid, endGrid); ArrayList<Grid> path = new ArrayList<Grid>(); while (resultGrid != null) { path.add(new Grid(resultGrid.x, resultGrid.y)); resultGrid = resultGrid.parent; } for (int i = 0; i < map.length; i++) { for (int j = 0; j < map[0].length; j++) { if (containGrid(path, i, j)&&map[i][j]=='-') { System.out.print("*\t"); } else { System.out.print(map[i][j] + "\t"); } } System.out.println(); } } }
input
10 ---------- ---------- ---#------ -S-#------ ---#-E---- ---#------ ---------- ---------- ---------- ---------- 10 ---------- ---------- ---#------ -S-#------ ---#------ ---#------ ---------- ---------- ---------- --------E-
output