数据结构☞图的表示

图的表示方式有两种:二维数组表示(邻接矩阵);链表表示(邻接表)

邻接矩阵

邻接矩阵是表示图形中顶点之间相邻关系的矩阵,对于n个顶点的图而言,矩阵是row和col表示的是1.....n个点,相连为1,不相连为0

邻接表

  • 邻接矩阵需要为每个顶点都分配n个边的空间,其实还有很多表都是不存在,会造成空间的一定损失。
  • 邻接表的实现只关心存在的边,不关心不存在的边。因此没有空间浪费,邻接表由数组+链表组成

代码实现

定义接口

public interface Graph {
    public void addEdge(int v, int w);
    public boolean hasEdge(int v, int w);
    public Iterable<Integer> adj(int v);
    public void show();
    public int n();
    public int m();
}

邻接矩阵代码实现

public class DenseGraph implements Graph {
    /**顶点数*/
    private int n;
    /**边数*/
    private int m;
    /**是否为有向图*/
    private boolean directed;
    /**图的具体数据*/
    private boolean[][] g;
    /**初始化没有任何边,定点之间的连接为false*/
    public DenseGraph(int n, boolean directed) {
        this.n = n;
        this.directed = directed;
        this.m = 0;
        g = new boolean[n][n];
    }
      /**为图增加一条边**/
    public void addEdge(int v,int w){
        if(hasEdge(v,w)){
            return;
        }
        g[v][w] = true;
        if(!directed){
            g[w][v] = true;
        }
        m++;
    }
    /**判断两个顶点之间有没有边**/
    public boolean hasEdge(int v,int w){
        assert v >= 0 && v < n;
        assert w >= 0 && w < n;
        return g[v][w];
    }
    /**返回图中一个顶点的所有邻边*/
    public Iterable<Integer> adj(int v){
        assert v >=0 && v < n;
        Vector<Integer> vector = new Vector();
        for(int i=0;i<n;i++){
            if(g[v][i]){
                vector.add(i);
            }
        }
        return   vector;
    }
    @Override
    public void show() {
        for(int i=0;i<n;i++){
            for (int j=0;j<n;j++){
                System.out.print(g[i][j]+"\t");
            }
            System.out.println();
        }
    }
    @Override
    public int n() {
        return n;
    }
    @Override
    public int m() {
        return m;
    }
}

邻接表代码实现

public class SparseGraph  implements Graph{
    /**顶点数*/
    private int n;
    /**边数*/
    private int m;
    /**是否为有向图*/
    private boolean directed;
    /**图的具体数据*/
     private Vector<Integer>[] g;
    public SparseGraph(int n,boolean directed) {
        this.n = n;
        this.m = 0;
        this.directed = directed;
        g = (Vector<Integer>[])new Vector[n];
       for(int i=0;i<n;i++){
          g[i] = new Vector<Integer>();
      }
    }

  /**向图中增加一条边*/
    public void addEdge(int v,int w){
        if(hasEdge(v,w)){
            return;
        }

        g[v].add(w);
        if(v != w && !directed){
            g[w].add(v);
        }
    }
/**验证图中是否有从v-w的边*/
    public boolean hasEdge(int v,int w){
        Vector<Integer> vector  =  g[v];
        for(int i=0;i<vector.size();i++){
            if(vector.elementAt(i)==w){
                return  true;
            }
        }
        return false;
    }
    /**返回图中一个顶点的所有邻边*/
    public Iterable<Integer> adj(int v){
        assert v >=0 && v < n;
        return  g[v];
    }
    @Override
    public void show() {
        for(int i=0;i<n;i++){
            System.out.print("vertex " + i + ":\t");
            for(int j=0;j<g[i].size();j++){
                System.out.print(g[i].elementAt(j)+"\t");
            }
            System.out.println();
        }
    }
  /**返回定点数*/
    @Override
    public int n() {
        return n;
    }
 /**返回边数*/
    @Override
    public int m() {
        return m;
    }
}
posted @ 2019-07-01 10:03  BingoJ  阅读(629)  评论(0编辑  收藏  举报