图论基础

图的定义

是一种比线性表和树更为复杂的数据结构,在图形结构中结点之间的关系可以是任意的,任意两个数据元素都可能存在相关性,因此图论在计算中应用相当广泛,知识图谱,推荐算法。

图的基本元素

结点,顶点,弧(边),弧尾,弧头,有向图(边右箭头),无向图,权(边的权重),子图(递归),出度,入度,回路。

java 如何将 GeoJson类型的数据进行制图_递归

图的数据结构

根据不同情况选择不同的结构来表示

  • 链表
  • 数组 (V,E)

图的表示方法:

数组即邻接矩阵: 数组data[B][F]=10 (V,E)
邻接表:链表	
B:->F->C->E
十字链表:为了更节约空间
多重邻接表 :

遍历方式

  • BFS:广度搜索,非递归的方式
  • DFS:深度搜索,递归的方式

BFS(广度搜索)

迷宫问题

有一天,小美和你去玩迷宫。但是方向感不好的小美很快就迷路了,你得知后便去解救无助的小美,你已经弄清楚了迷宫的地图,现在你要知道从你当前位置出发你是否能够达到
小美的位置?只可以前后左右走。

图的邻接矩阵如下:1表示障碍物,0表示没有障碍物,绿色代表当前我的位置,红色代表小美的位置。

0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

java 如何将 GeoJson类型的数据进行制图_ci_02


BFS思路

我的起始位置(1,1)这点,目标位置(4,3)这点,我们要判断这两点能不能通,转成图论。

从我当前的点,每次判断前后左右能不能走,如果可以走我就加入我的可到达的点。

(1,1)=>(1,2),(2,1)=>(2,2),(3,1)

把可以到达的点加入待走的队列中,每次判断再把点拿出来,然后把判断可以走的点继续放入队列。

按照这个步骤可以判断出我能达到的任意一个点。

具体代码如下

class Point {
	int x;
	int y;
}

public class BFS {

	// 定义一张图 我现在用矩阵的形式
	private int n; // 表示行
	private int m; // 表示列

	private int dx; // 表示目标位置的x坐标
	private int dy; // 表示目标位置的y坐标

	private int data[][]; // 表示图的矩阵
	private boolean mark[][]; // 用来标记我走过的路 防止死循环

	public BFS(int n, int m, int dx, int dy, int[][] data, boolean[][] mark) {
		super();
		this.n = n;
		this.m = m;
		this.dx = dx;
		this.dy = dy;
		this.data = data;
		this.mark = mark;
	}

	public void bfs(int startx, int starty) { // 表示我的起始位置
		mark[startx][starty] = true; // 表示我已经走过的点
		Queue<Point> queue = new ArrayBlockingQueue<>(n * m); // 队列的空间 有多少点就开多少
		Point start = new Point();
		start.x = startx;
		start.y = starty;
		queue.add(start); // 起始点加入队列
		// 定义一个方向向量
		int next[][] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };		//表示前后左右 二维数组
		

		while (!queue.isEmpty()) { // 队列不为空 就表示还可以走
			// 判断前后左右
			Point curPoint = queue.poll(); // 每次取队列的头 出队列
			for (int i = 0; i < 4; i++) {
				int nextx = curPoint.x + next[i][0];
				int nexty = curPoint.y + next[i][1];
				// 表示走前后左右的点,其实就是坐标系运算 y+1表示往下走了一步 x+1表示往左走了一步
				// 判断是否可以走
				System.out.println("下一个点:" + nextx + ":" + nexty);
				if (nextx < 1 || nextx > n || nexty < 1 || nexty > m)// 否则就出边了
					continue;
				if (!mark[nextx][nexty] && data[nextx][nexty] == 0) { // 判断有没有走过
					// 表示可以走
					// 判断是不是到了目的地
					if (nextx == dx && nexty == dy) {// 表示是目的地
						System.out.println("true");
						return;
					}
					Point newPoint = new Point();
					newPoint.x = nextx;
					newPoint.y = nexty;
					queue.add(newPoint);		//下一步加入队列 就是一步一步走下去了
					mark[nextx][nexty] = true;
				}

			}
		}
		System.out.println("false");
		return;
	}

	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int m = cin.nextInt();

		int data[][] = new int[n + 1][m + 1];
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				data[i][j] = cin.nextInt();
			}
		}
		int dx = cin.nextInt();
		int dy = cin.nextInt();
		boolean mark[][] = new boolean[n + 1][m + 1];
		BFS bfs = new BFS(n, m, dx, dy, data, mark);
		int startx = cin.nextInt();
		int starty = cin.nextInt();
		bfs.bfs(startx, starty);
	}

}
// 0 0 1 0
// 0 0 0 0
// 0 0 1 0
// 0 1 0 0
// 0 0 0 1

DFS(深度搜索)

同样还是上面那个问题,只不过,这次需要找到最快的路径

0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1

一般牵涉到最快以及路径就考虑用DFS

DFS思路

就是找到一个方向就一直走下去,直到不能走了为止。不能走了就回退,到之前
剩下没有走的方向

如下图所示,从1找到5

java 如何将 GeoJson类型的数据进行制图_System_03


代码如下

public class DFS {

    // 定义一张图 我现在用矩阵的形式
    private int n; // 表示行
    private int m; // 表示列

    private int dx; // 表示目标位置的x坐标
    private int dy; // 表示目标位置的y坐标

    private int data[][]; // 表示图的矩阵
    private boolean mark[][]; // 用来标记我走过的路 防止死循环
    ArrayList<Integer> steps; //存储每条路径的步数
    // 定义一个方向向量
    int next[][] = { { 0, 1 }, { 1, 0 }, { 0, -1 }, { -1, 0 } };

    public DFS(int n, int m, int dx, int dy, int[][] data, boolean[][] mark) {
        super();
        this.n = n;
        this.m = m;
        this.dx = dx;
        this.dy = dy;
        this.data = data;
        this.mark = mark;
        this.steps = new ArrayList<>();
    }

    //问题:写出 从 startx starty 计算出到 dx dy最短需要走几步路,用递归
    public void dfs(int x,int y,int step) {		//x 和 y表示当前走到的点,step表示走到当前已经走了几步了
        for (int[] ints : next){
            int nextx = x + ints[0];
            int nexty = y + ints[1];
            //判断当前点是否能走
            if (nextx < 1 || nextx > n || nexty < 1 || nexty > m || mark[nextx][nexty] || data[nextx][nexty] == 1){
                continue;
            }else {
                System.out.print("("+nextx+","+nexty+")");
                if (nextx == dx && nexty == dy){
                    steps.add(step);
                    System.out.println();
                }else{
                    mark[x][y] = true;
                    dfs(nextx,nexty,++step);
                    step--;
                    mark[x][y] = false;
                }
            }
        }
    }

    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n = cin.nextInt();
        int m = cin.nextInt();

        int data[][] = new int[n + 1][m + 1];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                data[i][j] = cin.nextInt();
            }
        }
        int dx = cin.nextInt();
        int dy = cin.nextInt();
        boolean mark[][] = new boolean[n + 1][m + 1];
        DFS bfs = new DFS(n, m, dx, dy, data, mark);
        int startx = cin.nextInt();
        int starty = cin.nextInt();
        问题:写出 从 startx starty 计算出到 dx dy最短需要走几步路,用递归
        bfs.dfs(startx, starty,1);

        for (Integer integer : bfs.steps){
            System.out.println(integer);
        }
    }

}
// 0 0 1 0
// 0 0 0 0
// 0 0 1 0
// 0 1 0 0
// 0 0 0 1

应用场景

知识图谱:最推荐从这里如入手。

图形数据库 Neo4J。

推荐关系:猜你喜欢

java 如何将 GeoJson类型的数据进行制图_递归_04


java 如何将 GeoJson类型的数据进行制图_ci_05


java 如何将 GeoJson类型的数据进行制图_ci_06