浅谈图的存储结构与遍历

浅谈图的存储结构与遍历

简述图的存储结构

  图的存储结构分为:邻接矩阵与邻接表

  

  邻接矩阵分为顶点、边表(1代表存在边、0代表不存在)。

  邻接链表分为顶点(顶点信息、第一个边结点)、边表(顶点序号、下一个边结点)。

  领结链表数据结构:

public class VertexNode {
    private String vertex;
    private EdgeNode firstEdge;
}
//边表结点
public class EdgeNode {
    private int edge;
    private EdgeNode next;
}

图的遍历原理

  遍历:深度遍历、广度遍历。

  深度遍历类似于树的前序遍历,遇见结点就访问。

  广度遍历类似于树的层序遍历,先把结点入队,当结点出队的时候,访问该节点,把该节点的邻接结点入队。

  以邻接矩阵为例分析:

  深度遍历的访问过程:

  1. 访问V0,判断V0的是否被 访问标记为true,如果为true则不继续访问。如果为false,扫描edge[0][0]—edge[0][n]。
  2. 发现edge[0][3]==1,则访问V1。按照步骤一访问,剩余的都按照这种方式继续访问。
  3. 访问顺序为V0-V1-V2-V3。

  广度遍历的访问过程:

  1. 访问结点V0,V0入队。
  2. 判断队列为空,如果不为空,队头出队即V0出队并且打印结点信息。
  3. 判断V0的边是否被访问过,若没有被访问过则全部入队,即V1、V3入队。
  4. 依次按照循环1-3步骤直到队列为空
  5. 访问顺序:V0-V1-V3-V2

图遍历代码实现

public interface BaseGraph {
    //深度优先遍历-类似于前序遍历
    void DFSTraverse(int v);
    //广度优先遍历-类似于层序遍历
    void BFSTraverse(int v);
}

邻接矩阵代码实现

public class AdjMatrixGraph implements BaseGraph {
    public static final int MAX_SIZE=20;
    //图的顶点数
    private int vertexNum;
    //图的边数
    private int edgeNum;
    
    private int edge[][];
    
    private String vertex[];
    
    private boolean isDFSVisited[];
    
    private boolean isBFSVisited[];

    /**
     * @param vertex 图的顶点
     * @param n 图的顶点数
     * @param e    图的边数
     */
    public AdjMatrixGraph(String vertex[],int n,int e) {
        this.vertexNum=n;
        this.edgeNum=e;
        isDFSVisited=new boolean[vertexNum];
        isBFSVisited=new boolean[vertexNum];
        this.edge=new int[vertexNum][vertexNum];
        this.vertex=new String[vertexNum];
        //初始化顶点
        for(int i=0;i<vertexNum;i++){
            this.vertex[i]=vertex[i];
        }
        
        //初始化边表
        for(int row=0;row<vertexNum;row++){
            for(int colunmNum=0;colunmNum<vertexNum;colunmNum++){
                edge[row][colunmNum]=0;
            }
        }
        
        Scanner sc=new Scanner(System.in);
        //输入边表信息
        for(int k=0;k<edgeNum;k++){
            //领阶矩阵的行号
            int rowNum=sc.nextInt();
            //领阶矩阵的列号
            int colunmNum=sc.nextInt();
            edge[rowNum][colunmNum]=1;
            edge[colunmNum][rowNum]=1;
        }
    }

    /**
     * 深度优先遍历
     */
    @Override
    public void DFSTraverse(int v) {
        System.out.print(vertex[v]+"\t");
        isDFSVisited[v]=true;
        for(int j=0;j<vertexNum;j++){
            if(edge[v][j]==1&&isDFSVisited[j]==false){
                DFSTraverse(j);
            }
        }
    }

    /**
     * 广(宽)度优先遍历
     */
    @Override
    public void BFSTraverse(int v) {
        Queue<Integer> queue=new LinkedList<Integer>();
        System.out.print(vertex[v]+"\t");
        isBFSVisited[v]=true;
        queue.add(v);
        while(!queue.isEmpty()){
            v=queue.poll();
            for(int j=0;j<vertexNum;j++){
                if(edge[v][j]==1&&isBFSVisited[j]==false){
                    System.out.print(vertex[j]+"\t");
                    isBFSVisited[j]=true;
                    queue.add(j);
                }
            }
        }
    }
    
    public static void main(String[] args) {
        String [] vertex=new String[]{"vo","v1","v2","v3"};
        AdjMatrixGraph graph=new AdjMatrixGraph(vertex, 4, 4);
        //图的深度遍历
        System.out.println("图的深度遍历");
        graph.DFSTraverse(0);
        //图的广度遍历
        System.out.println("");
        System.out.println("图的广度遍历");
        graph.BFSTraverse(0);
    }
}

 

邻接表代码实现

public class AdjListGraph implements BaseGraph{
    
    private int vertexNum;
    private int edgeNum;
    private VertexNode [] adjList;
    private boolean isDFSVisited[];
    private boolean isBFSVisited[];
    
    public AdjListGraph(String vertexs[],int vertexNum,int edgeNum) {
        this.vertexNum=vertexNum;
        this.edgeNum=edgeNum;
        adjList=new VertexNode[vertexNum];
        isDFSVisited=new boolean[vertexNum];
        isBFSVisited=new boolean[vertexNum];
        //初始化
        for(int i=0;i<vertexNum;i++){
            adjList[i]=new VertexNode();
            adjList[i].setVertex(vertexs[i]);
            adjList[i].setFirstEdge(null);
        }
        
        Scanner sc=new Scanner(System.in);
        for(int k=0;k<edgeNum;k++){
            int i=sc.nextInt();//第几号节点
            int j=sc.nextInt();//链接边节点
            EdgeNode eNode=new EdgeNode(j,adjList[i].getFirstEdge());
            adjList[i].setFirstEdge(eNode);
        }
    }
    
    @Override
    public void DFSTraverse(int v) {
        System.out.println(adjList[v].getVertex());
        isDFSVisited[v]=true;
        EdgeNode p=adjList[v].getFirstEdge();
        while(p!=null){
            int j=p.getEdge();
            if(isDFSVisited[j]==false)
                DFSTraverse(j);
            p=p.getNext();
        }
    }

    @Override
    public void BFSTraverse(int v) {
        Queue<Integer> queue=new LinkedList<Integer>();
        System.out.println(adjList[v].getVertex());
        isBFSVisited[v]=true;
        queue.add(v);
        while(!queue.isEmpty()){
            v=queue.poll();
            EdgeNode p=adjList[v].getFirstEdge();
            while(p!=null){
                int j=p.getEdge();
                if(isBFSVisited[j]==false){
                    System.out.println(adjList[j].getVertex());
                    isBFSVisited[j]=true;
                    queue.add(j);
                }
                p=p.getNext();
            }
        }
    }
    
    public static void main(String[] args) {
        String [] vertexs=new String[]{"vo","v1","v2","v3"};
        AdjListGraph graph=new AdjListGraph(vertexs, 4,4);
        graph.DFSTraverse(0);
        graph.BFSTraverse(0);
    }
    
}
posted @ 2017-05-12 08:35 邱勇Aries 阅读( ...) 评论( ...) 编辑 收藏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值