数据结构与算法之图
1.图的使用场景一般是关系型的数据载体搭建,图的表示通常可以是邻接矩阵或邻接链表,各自都有优缺点,邻接矩阵快,邻接链表占内存小
2.图的搜索,分为深度优先(DFS)和广度优先(BFS):
深度优先:从某个节点开始一路往下走到不能再走或找到目标值为止
广度优先:从某个节点开始,一次只移动一层,但这一层要将与该节点关联的所有情况都包含进去,然后进入下一层依次往下继续重复上述步骤
3.下面是代码:
3.1 BFS.java
package com.hfm.util; import java.util.Objects; class Point{ int x; int y; int data; public Point(int x, int y,int data) { this.x = x; this.y = y; this.data = data; } @Override public String toString() { return "Point{" + "x=" + x + ", y=" + y + ", data=" + data + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Point point = (Point) o; return x == point.x && y == point.y && data == point.data; } @Override public int hashCode() { return Objects.hash(x, y, data); } } public class BFS { Point dest; //目标位置 Point start; //开始位置 Point map[][]; //地图点 int hlen; int vlen; Point direct[] = { new Point(0,-1,0), new Point(1,0,0), new Point(0,1,0), new Point(-1,0,0), }; public BFS(Point dest, Point start, Point[][] map,int hlen,int vlen) { this.dest = dest; this.start = start; this.map = map; this.hlen = hlen; this.vlen = vlen; } public void search(){ boolean mark[][] = new boolean[hlen][vlen]; mark[start.x][start.y] = true; Point cur = start; int max = 0; boolean finished = false; while (max<hlen*vlen&&!finished){ for (int i = 0; i < direct.length; i++) { int hindex = cur.x+direct[i].x; int vindex = cur.y+direct[i].y; if(hindex<0||hindex>hlen-1||vindex<0||vindex>vlen-1) continue; if(!mark[hindex][vindex]){ Point newPoint = new Point(hindex,vindex,map[hindex][vindex].data); mark[hindex][vindex] = true; if(newPoint.equals(dest)){ System.out.println("找到了,在["+hindex+","+vindex+"]"); finished = true; break; } max++; } } cur = map[max/vlen][max%vlen]; } if(max >= hlen*vlen) System.out.println("没有找到"); } public static void main(String[] args) { int mapData[][] = { {0,0,1,0}, {0,0,0,0}, {0,0,1,0}, {0,1,0,0}, {0,0,0,1}, }; int row = 5; int col = 4; Point map[][] = new Point[row][col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { map[i][j] = new Point(i,j,mapData[i][j]); } } BFS bfs = new BFS(map[2][3],map[0][0],map,row,col); bfs.search(); } }
3.2.DFS.java
package com.hfm.util; public class DFS { Point dest; //目标位置 Point start; //开始位置 Point map[][]; //地图点 int hlen; int vlen; boolean mark[][]; int minStep = Integer.MAX_VALUE; String trace ; Point direct[] = { new Point(0,-1,0), new Point(1,0,0), new Point(0,1,0), new Point(-1,0,0), }; public DFS(Point dest, Point start, Point[][] map,int hlen,int vlen) { this.dest = dest; this.start = start; this.map = map; this.hlen = hlen; this.vlen = vlen; this.mark = new boolean[hlen][vlen]; mark[start.x][start.y] = true; } public void search(Point cur,int step,String trace){ if(cur.equals(dest)){ this.minStep = step<this.minStep?step:this.minStep; this.trace = trace; return; } for (int i = 0; i < direct.length; i++) { int hindex = cur.x+direct[i].x; int vindex = cur.y+direct[i].y; if(hindex<0||hindex>hlen-1||vindex<0||vindex>vlen-1) continue; if(!mark[hindex][vindex]&&map[hindex][vindex].data==0){ mark[hindex][vindex] = true; search(map[hindex][vindex],step+1,trace+"->["+map[hindex][vindex].x+","+map[hindex][vindex].y+"]"); mark[hindex][vindex] = false; } } } public static void main(String[] args) { int mapData[][] = { {0,0,1,0}, {0,0,0,0}, {0,0,1,0}, {0,1,0,0}, {0,0,0,1}, }; int row = 5; int col = 4; Point map[][] = new Point[row][col]; for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { map[i][j] = new Point(i,j,mapData[i][j]); } } DFS dfs = new DFS(map[2][3],map[0][0],map,row,col); dfs.search(map[0][0],0,"["+map[0][0].x+","+map[0][0].y+"]"); System.out.println(dfs.minStep); System.out.println(dfs.trace); } }
上述解决的问题,广度优先算法是逐个找,找到时输出目标所在的节点位置,值为1表示该节点不能通过,0表示可以通过
深度优先是一直找,找到是输出最短路径和走过的路径下标,值为1表示该节点不能通过,0表示可以通过

DFS运行结果:


浙公网安备 33010602011771号