浅谈图的存储结构与遍历

简述图的存储结构

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

  

  邻接矩阵分为顶点、边表(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  码农皮邱  阅读(627)  评论(0)    收藏  举报