图 的入门介绍

图的定义和应用

  • 图的定义
    • 图是由一组顶点 和 能够将两个顶点相连的边组成的
  • 图的应用
    • 地图

无向图

图的术语
在这里插入图片描述
要表示一幅图,需要表示清楚部分内容

  • 图中所有的顶点
  • 所有顶点的边

下面是实现一个 无加权 无向图的Api
在这里插入图片描述


import java.util.LinkedList;
import java.util.Queue;

/**
 * 无加权 无向图
 */
public class Graph {
    
    
    /**
     * 图中 顶点数
     */
    private final int V;

    /**
     * 记录图中边的数量
     */
    private int E;

    /**
     * 邻接表
     */
    private Queue< Integer >[] adj;

    public Graph (int v) {
    
    
        this.V = v;
        this.E = 0;
        adj = new Queue[v];
        for (int i = 0; i < v; ++i) {
    
    
            adj[i] = new LinkedList<>();
        }
    }

    /**
     * 获得图的顶点数量
     *
     * @return
     */
    public int V () {
    
    
        return V;
    }

    /**
     * 获得图中边的数量
     *
     * @return
     */
    public int E () {
    
    
        return E;
    }

    /**
     * 顶点v 和 顶点w 之间关联起来 v - w
     *
     * @param v
     * @param w
     */
    public void addEage (int v, int w) {
    
    
        adj[v].add(w);
        adj[w].add(v);
    }

    /**
     * 获取v 顶点关联的所有顶点
     *
     * @param v
     * @return
     */
    public Queue adj (int v) {
    
    
        return adj[v];
    }
}

图的搜索

  • 深度优先搜索
    深度优先搜索,是指在搜索的时候,遍历一个结点的子结点,发现子结点还有子结点,先向下搜索 ,回溯返回回来 在搜索兄弟结点
/**
 * 深度优先搜索
 */
public class DepthFirstSearch {
    
    
    /**
     * 记录结点是否被搜索过,应为图可能是连通的 ,搜索会进入死循环
     */
    private boolean[] marked;

    /**
     * 记录图中多少个结点和 我们传入的v结点相联通
     */
    private int count;

    /**
     * 传入一个图,和一个要搜索的结点
     * @param g
     * @param v
     */
    public DepthFirstSearch (Graph G , int v) {
    
    
        marked = new boolean[G.V()];
        count = 0;
        dfs(G,v);
    }

    private void dfs (Graph G , int v) {
    
    
        marked[v] = true;
        for (Integer w : G.adj(v)) {
    
    
            if (!marked[w])
                dfs(G,w);
        }
        ++count;
    }

    /**
     * 判断w 和 v 顶点是否相通
     * @param w
     * @return
     */
    public boolean marked (int w) {
    
    
        return marked[w];
    }

}

  • 广度优先搜索
    广度优先搜索的时候,指的是在搜索时,如果遇到一个结点 既有子结点 又有兄弟结点,先搜索兄弟结点后 在搜索子结点,(层次遍历)

/**
 * 广度优先搜索
 */
public class BreathFirstSearch {
    
    
    /**
     * 记录结点是否被搜索到
     */
    private boolean[] marked;

    /**
     * 与传入的结点v 能搜索到的结点的数量
     */
    private int count;

    /**
     * 用一个队列才层次遍历图
     */
    private Queue<Integer> waitQueue;

    /**
     * 初始化 将从v 出发能够的搜索到的结点 全部记录在了 marked中
     * @param G
     * @param v
     */
    public BreathFirstSearch (Graph G, int v) {
    
    
        marked = new boolean[G.V()];
        count = 0;
        waitQueue = new LinkedList<Integer>();
        waitQueue.add(v);
        bfs(G,v);
    }

    private void bfs (Graph G, int w) {
    
    
        marked[w] = true;
        while (!waitQueue.isEmpty()) {
    
    
            Integer pollNode = waitQueue.poll();
            for (Integer adj : G.adj(pollNode)) {
    
    
                if (!marked[adj])
                    bfs(G,adj);
            }
        }
        ++count;
    }

    /**
     * 判断顶点w 和 v 是否相同
     * @param w
     * @return
     */
    public boolean marked (int w) {
    
    
        return marked[w];
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45844836/article/details/113834941