zoukankan      html  css  js  c++  java
  • 浅谈图的存储结构与遍历

    简述图的存储结构

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

      

      邻接矩阵分为顶点、边表(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;
    
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> edge[][];
    
    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String vertex[];
    
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> isDFSVisited[];
    
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> isBFSVisited[];
    
    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> vertex 图的顶点
     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> n 图的顶点数
     * </span><span style="color: #808080;">@param</span><span style="color: #008000;"> e    图的边数
     </span><span style="color: #008000;">*/</span>
    <span style="color: #0000ff;">public</span> AdjMatrixGraph(String vertex[],<span style="color: #0000ff;">int</span> n,<span style="color: #0000ff;">int</span><span style="color: #000000;"> e) {
        </span><span style="color: #0000ff;">this</span>.vertexNum=<span style="color: #000000;">n;
        </span><span style="color: #0000ff;">this</span>.edgeNum=<span style="color: #000000;">e;
        isDFSVisited</span>=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;">[vertexNum];
        isBFSVisited</span>=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;">[vertexNum];
        </span><span style="color: #0000ff;">this</span>.edge=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">int</span><span style="color: #000000;">[vertexNum][vertexNum];
        </span><span style="color: #0000ff;">this</span>.vertex=<span style="color: #0000ff;">new</span><span style="color: #000000;"> String[vertexNum];
        </span><span style="color: #008000;">//</span><span style="color: #008000;">初始化顶点</span>
        <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=0;i&lt;vertexNum;i++<span style="color: #000000;">){
            </span><span style="color: #0000ff;">this</span>.vertex[i]=<span style="color: #000000;">vertex[i];
        }
        
        </span><span style="color: #008000;">//</span><span style="color: #008000;">初始化边表</span>
        <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> row=0;row&lt;vertexNum;row++<span style="color: #000000;">){
            </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> colunmNum=0;colunmNum&lt;vertexNum;colunmNum++<span style="color: #000000;">){
                edge[row][colunmNum]</span>=0<span style="color: #000000;">;
            }
        }
        
        Scanner sc</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> Scanner(System.in);
        </span><span style="color: #008000;">//</span><span style="color: #008000;">输入边表信息</span>
        <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> k=0;k&lt;edgeNum;k++<span style="color: #000000;">){
            </span><span style="color: #008000;">//</span><span style="color: #008000;">领阶矩阵的行号</span>
            <span style="color: #0000ff;">int</span> rowNum=<span style="color: #000000;">sc.nextInt();
            </span><span style="color: #008000;">//</span><span style="color: #008000;">领阶矩阵的列号</span>
            <span style="color: #0000ff;">int</span> colunmNum=<span style="color: #000000;">sc.nextInt();
            edge[rowNum][colunmNum]</span>=1<span style="color: #000000;">;
            edge[colunmNum][rowNum]</span>=1<span style="color: #000000;">;
        }
    }
    
    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 深度优先遍历
     </span><span style="color: #008000;">*/</span><span style="color: #000000;">
    @Override
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> DFSTraverse(<span style="color: #0000ff;">int</span><span style="color: #000000;"> v) {
        System.out.print(vertex[v]</span>+"	"<span style="color: #000000;">);
        isDFSVisited[v]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
        </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> j=0;j&lt;vertexNum;j++<span style="color: #000000;">){
            </span><span style="color: #0000ff;">if</span>(edge[v][j]==1&amp;&amp;isDFSVisited[j]==<span style="color: #0000ff;">false</span><span style="color: #000000;">){
                DFSTraverse(j);
            }
        }
    }
    
    </span><span style="color: #008000;">/**</span><span style="color: #008000;">
     * 广(宽)度优先遍历
     </span><span style="color: #008000;">*/</span><span style="color: #000000;">
    @Override
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> BFSTraverse(<span style="color: #0000ff;">int</span><span style="color: #000000;"> v) {
        Queue</span>&lt;Integer&gt; queue=<span style="color: #0000ff;">new</span> LinkedList&lt;Integer&gt;<span style="color: #000000;">();
        System.out.print(vertex[v]</span>+"	"<span style="color: #000000;">);
        isBFSVisited[v]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
        queue.add(v);
        </span><span style="color: #0000ff;">while</span>(!<span style="color: #000000;">queue.isEmpty()){
            v</span>=<span style="color: #000000;">queue.poll();
            </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> j=0;j&lt;vertexNum;j++<span style="color: #000000;">){
                </span><span style="color: #0000ff;">if</span>(edge[v][j]==1&amp;&amp;isBFSVisited[j]==<span style="color: #0000ff;">false</span><span style="color: #000000;">){
                    System.out.print(vertex[j]</span>+"	"<span style="color: #000000;">);
                    isBFSVisited[j]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
                    queue.add(j);
                }
            }
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        String [] vertex</span>=<span style="color: #0000ff;">new</span> String[]{"vo","v1","v2","v3"<span style="color: #000000;">};
        AdjMatrixGraph graph</span>=<span style="color: #0000ff;">new</span> AdjMatrixGraph(vertex, 4, 4<span style="color: #000000;">);
        </span><span style="color: #008000;">//</span><span style="color: #008000;">图的深度遍历</span>
        System.out.println("图的深度遍历"<span style="color: #000000;">);
        graph.DFSTraverse(</span>0<span style="color: #000000;">);
        </span><span style="color: #008000;">//</span><span style="color: #008000;">图的广度遍历</span>
        System.out.println(""<span style="color: #000000;">);
        System.out.println(</span>"图的广度遍历"<span style="color: #000000;">);
        graph.BFSTraverse(</span>0<span style="color: #000000;">);
    }
    

    }

     

    邻接表代码实现

    public class AdjListGraph implements BaseGraph{
    
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> vertexNum;
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">int</span><span style="color: #000000;"> edgeNum;
    </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> VertexNode [] adjList;
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> isDFSVisited[];
    </span><span style="color: #0000ff;">private</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;"> isBFSVisited[];
    
    </span><span style="color: #0000ff;">public</span> AdjListGraph(String vertexs[],<span style="color: #0000ff;">int</span> vertexNum,<span style="color: #0000ff;">int</span><span style="color: #000000;"> edgeNum) {
        </span><span style="color: #0000ff;">this</span>.vertexNum=<span style="color: #000000;">vertexNum;
        </span><span style="color: #0000ff;">this</span>.edgeNum=<span style="color: #000000;">edgeNum;
        adjList</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> VertexNode[vertexNum];
        isDFSVisited</span>=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;">[vertexNum];
        isBFSVisited</span>=<span style="color: #0000ff;">new</span> <span style="color: #0000ff;">boolean</span><span style="color: #000000;">[vertexNum];
        </span><span style="color: #008000;">//</span><span style="color: #008000;">初始化</span>
        <span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> i=0;i&lt;vertexNum;i++<span style="color: #000000;">){
            adjList[i]</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> VertexNode();
            adjList[i].setVertex(vertexs[i]);
            adjList[i].setFirstEdge(</span><span style="color: #0000ff;">null</span><span style="color: #000000;">);
        }
        
        Scanner sc</span>=<span style="color: #0000ff;">new</span><span style="color: #000000;"> Scanner(System.in);
        </span><span style="color: #0000ff;">for</span>(<span style="color: #0000ff;">int</span> k=0;k&lt;edgeNum;k++<span style="color: #000000;">){
            </span><span style="color: #0000ff;">int</span> i=sc.nextInt();<span style="color: #008000;">//</span><span style="color: #008000;">第几号节点</span>
            <span style="color: #0000ff;">int</span> j=sc.nextInt();<span style="color: #008000;">//</span><span style="color: #008000;">链接边节点</span>
            EdgeNode eNode=<span style="color: #0000ff;">new</span><span style="color: #000000;"> EdgeNode(j,adjList[i].getFirstEdge());
            adjList[i].setFirstEdge(eNode);
        }
    }
    
    @Override
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> DFSTraverse(<span style="color: #0000ff;">int</span><span style="color: #000000;"> v) {
        System.out.println(adjList[v].getVertex());
        isDFSVisited[v]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
        EdgeNode p</span>=<span style="color: #000000;">adjList[v].getFirstEdge();
        </span><span style="color: #0000ff;">while</span>(p!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
            </span><span style="color: #0000ff;">int</span> j=<span style="color: #000000;">p.getEdge();
            </span><span style="color: #0000ff;">if</span>(isDFSVisited[j]==<span style="color: #0000ff;">false</span><span style="color: #000000;">)
                DFSTraverse(j);
            p</span>=<span style="color: #000000;">p.getNext();
        }
    }
    
    @Override
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> BFSTraverse(<span style="color: #0000ff;">int</span><span style="color: #000000;"> v) {
        Queue</span>&lt;Integer&gt; queue=<span style="color: #0000ff;">new</span> LinkedList&lt;Integer&gt;<span style="color: #000000;">();
        System.out.println(adjList[v].getVertex());
        isBFSVisited[v]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
        queue.add(v);
        </span><span style="color: #0000ff;">while</span>(!<span style="color: #000000;">queue.isEmpty()){
            v</span>=<span style="color: #000000;">queue.poll();
            EdgeNode p</span>=<span style="color: #000000;">adjList[v].getFirstEdge();
            </span><span style="color: #0000ff;">while</span>(p!=<span style="color: #0000ff;">null</span><span style="color: #000000;">){
                </span><span style="color: #0000ff;">int</span> j=<span style="color: #000000;">p.getEdge();
                </span><span style="color: #0000ff;">if</span>(isBFSVisited[j]==<span style="color: #0000ff;">false</span><span style="color: #000000;">){
                    System.out.println(adjList[j].getVertex());
                    isBFSVisited[j]</span>=<span style="color: #0000ff;">true</span><span style="color: #000000;">;
                    queue.add(j);
                }
                p</span>=<span style="color: #000000;">p.getNext();
            }
        }
    }
    
    </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">void</span><span style="color: #000000;"> main(String[] args) {
        String [] vertexs</span>=<span style="color: #0000ff;">new</span> String[]{"vo","v1","v2","v3"<span style="color: #000000;">};
        AdjListGraph graph</span>=<span style="color: #0000ff;">new</span> AdjListGraph(vertexs, 4,4<span style="color: #000000;">);
        graph.DFSTraverse(</span>0<span style="color: #000000;">);
        graph.BFSTraverse(</span>0<span style="color: #000000;">);
    }
    

    }

  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/qiuyong/p/6842781.html
Copyright © 2011-2022 走看看