图--无向图

无向图

图是由一组顶点和一组能够将两个顶点相连的边组成的

采用邻接表数组的数据结构
无向图的API

public classGraph-
Graph(int v)
Graph(In in)
intV()顶点数
intE()边数
voidaddEdge(int v, int w)添加边v-w
Iterableadj(int v)和v相邻的所有顶点
StringtoString()

深度优先搜索

寻找离起点更远的顶点,只在碰到死胡同时才访问近处的顶点

public class DepthFirstSearch{
    private boolean[] marked;
    private int count;

    public DepthFirstSearch(Graph g, int s){
        marked = new boolean[g.V()];
        dfs(g,s);
    }

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

    public boolean marked(int w){
        return marked[w];
    }

    public int count(){
        return count;
    }

广度优先搜索

首先覆盖起点附近的顶点,只在临近的所有顶点都被访问了之后才向前前进
应用于寻找单点最短路径

public class BreadthFirstPaths {
    private boolean[] marked;
    private int[] edgeTo; //到达该顶点的已知路径上的最后一个顶点
    private final int s;   //起点

    public BreadthFirstPaths(Graph g, int s){
        marked = new boolean[g.V()];
        edgeTo = new int[g.V()];
        this.s = s;
        bfs(g, s);
    }

    public void bfs(Graph g, int s){
        Queue<Integer> queue = new Queue<>(); //先进先出
        marked[s] = true;
        queue.enqueue(s);
        while(!queue.isEmpty()){
            int v = queue.dequeue();
            for(int w : g.adj(v)){
                edgeTo[w] = v;
                marked[w] = true;
                queue.enqueue(w);
            }
        }
    }

    public boolean hasPathTo(int v){
        return marked[v];
    }

    public Iterable<Integer> pathTo(int v){
        if(!hasPathTo(v)) return null;
        Stack<Integer> path = new Stack<>();
        for(int x = v; x != s; x = edgeTo[x])
            path.push(x);
        path.push(s);
        return path; //s-v最短路径
    }
}

连通分量

在无向图中,如果从顶点vi到顶点vj有路径,则称vi和vj连通。如果图中任意两个顶点之间都连通,则称该图为连通图,否则,称该图为非连通图,则其中的连通子图称为连通分量

使用深度优先搜索找出图中的所有连通分量

public class CC {
    private boolean[] marked;
    private int count;
    public int[] id; //算法实现基于一个由顶点索引的数组id[]

    public CC(Graph g){
        marked = new boolean[g.V()];
        for(int s=0; s < g.V(); s++)
        dfs(g,s);
        count++;   //连通分量标号count
    }

    private void dfs(Graph g, int v){
        marked[v] = true;
        id[v] = count; //可连接到的同属一个count
        for(int w : g.adj(v))
            if(!marked[w]) dfs(g, w);   //递归
    }

    public boolean connected(int v, int w){
        return id[v]==id[w];
    }

    public int count(){
        return count;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值