数据结构与算法之图

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运行结果:

posted @ 2021-05-04 09:42  漂渡  阅读(79)  评论(0编辑  收藏  举报