图和图的遍历算法

图和图的遍历算法

1.存储结构(邻接链表)

1.1每个顶点用VexNode类表示,每条边用ArcNode表示

1.2所有顶点用数组VexNode adjlist[]表示,所有邻接顶点用链表表示

2.遍历算法

2.1深度优先遍历DFS

用递归实现,从V0开始,访问V0即邻接顶点V1,访问V1及其邻接顶点...

2.2广度优先遍历

用队列实现,从V0开始,访问V0,入队,出队,访问V0所有临界点,入队...直到队列为空

Graph.java

  1 package com.gxf.graph;
  2 
  3 /**
  4  * 定义一个图类
  5  * 包过构造方法
  6  * 插入顶点
  7  * 插入边
  8  * 深度优先遍历
  9  * 广度优先遍历
 10  * @author Administrator
 11  *
 12  */
 13 public class Graph {
 14     int n;
 15     int max;//当前顶点数和最大定点数
 16     VexNode adjlist[];//邻接链表存储结构
 17     boolean visited[];//标记顶点访问状态
 18     
 19     /**
 20      * 构造一个长度为l的邻接链表
 21      * @param l
 22      */
 23     public Graph(int l){
 24         n = 0;
 25         max = l;
 26         adjlist = new VexNode[l];
 27         visited = new boolean[l];
 28     }
 29     
 30     /**
 31      * 递归调用实现深度优先遍历
 32      * @param v0待遍历结点
 33      * @param vs访问函数类对象
 34      */
 35     public void dfs0(int v0, Visit vs){
 36         ArcNode p = adjlist[v0].firstArc;//node边结点
 37         
 38         if(!visited[v0]){//结点没有被访问过
 39             vs.visit(v0);//访问这个结点
 40             visited[v0] = true;//标记结点已经被访问
 41         }
 42         while(null != p){
 43             int v = p.adjvex;
 44             if(!visited[v]) 
 45                 dfs0(v, vs);//邻接顶点没有被访问,深度访问该顶点
 46             p = p.next;//深度访问结束,回退访问下一个邻接顶点
 47         }
 48     }
 49     
 50     /**
 51      * 向类的调用者提供一个调用接口
 52      * 初始化visited[]
 53      * 调用dfs0(int, vs)
 54      * @param v0
 55      * @param vs
 56      */
 57     public void dfs(int v0, Visit vs){
 58         for(int i = 0; i < max; i++){
 59             visited[i] = false;
 60         }//初始化visited[]数组
 61         dfs0(v0, vs);
 62     }
 63     
 64     /**
 65      * 广度优先遍历
 66      * 邻接链表用的是数组存储,只要用int节可以找到v0对应的顶点
 67      * @param v0
 68      * @param vs
 69      */
 70     public void bfs(int v0, Visit vs){
 71         int front = 0;
 72         int rear = 0;//队列头尾指针初始化为0
 73         int queue[] = new int[100];//队列
 74         int headVex;
 75         
 76         //没有递归调用可以初始化visited[]数组
 77         for(int i = 0; i < max; i++){
 78             visited[i] = false;
 79         }
 80         
 81         vs.visit(v0);
 82         visited[v0] = true;//访问v0顶点,访问过的顶点入队,队列里所有顶点都是访问过的 
 83         queue[rear++] = v0;//顶点入队
 84         
 85         while(front != rear){//队列不为空
 86             headVex = queue[front++];//出队 队列里面都是访问过的顶点
 87             ArcNode firstArc = adjlist[headVex].firstArc;//第一条边结点
 88             while(null != firstArc){//边结点不为空,有邻接点
 89                 if(!visited[firstArc.adjvex]){//邻接顶点没有被访问过
 90                     vs.visit(firstArc.adjvex);//访问邻接顶点
 91                     visited[firstArc.adjvex] = true;
 92                     queue[rear++] = firstArc.adjvex;//入队
 93                 }
 94                 firstArc = firstArc.next;//下一个邻接顶点
 95             }
 96         }
 97     }
 98     /**
 99      * 向图中插入一个顶点
100      * @param data
101      */
102     public void insertVex(int data){
103         if(n < max){//没有超过最大定点数
104             VexNode vexInsert = new VexNode();
105             vexInsert.data = data;
106             adjlist[n++] = vexInsert;
107             vexInsert.firstArc = null;
108             //n++;
109         }
110     }
111     
112     /**
113      * 在顶点v0和v1中间插入一条边结点
114      * 在v0和v1的链表中都需要插入一个边结点
115      * @param v0
116      * @param v1
117      */
118     public void insertEdge(int v0, int v1){
119         ArcNode arcNode0 = new ArcNode();//插入v0链表中的边结点
120         ArcNode arcNode1 = new ArcNode();//插入v1链表中的边结点
121         
122         VexNode vex0 = adjlist[v0];
123         
124         VexNode vex1 = adjlist[v1];
125         
126         arcNode0.next = vex0.firstArc;
127         arcNode1.next = vex1.firstArc;
128         
129         vex0.firstArc = arcNode0;
130         vex1.firstArc = arcNode1;//采用头插法插入到链表中
131         
132         arcNode0.adjvex = v1;
133         arcNode1.adjvex = v0;
134     }
135 }

VexNode.java

 1 package com.gxf.graph;
 2 
 3 /**
 4  * 邻接链表中顶点类
 5  * data结点内容
 6  * firstArc第一条边结点
 7  * @author Administrator
 8  *
 9  */
10 public class VexNode {
11     int data;
12     ArcNode firstArc;
13 
14 }
15 /**
16  * 邻接链表中边结点类
17  * 一条边对应一个ArcNode
18  * adjnode邻接顶点
19  * next下一条边
20  * @author Administrator
21  *
22  */
23 class ArcNode{
24     int adjvex;
25     ArcNode next;
26 }

Visit.java

 1 package com.gxf.graph;
 2 
 3 public class Visit {
 4     public String nodeString;
 5     public Visit(){
 6         nodeString = new String();
 7     }
 8     
 9     public void visit(int v){
10         nodeString += v + " ";
11 //        System.out.print(v + " ");
12     }
13     public String toString(){
14         return nodeString;
15     }
16 }

Test.java

 1 package com.gxf.graph;
 2 
 3 /**
 4  * 测试图的DFS和BFS
 5  * 插入四个顶点
 6  * 插入边形成连通图
 7  * @author Administrator
 8  *
 9  */
10 public class Test {
11 
12     public static void main(String[] args) {
13         Graph graph = new Graph(10);//创建四个顶点的图
14         Visit visit = new Visit();
15         //插入四个顶点
16         for(int i = 0; i < 4; i++){
17             graph.insertVex(i);
18         }
19         //插入边
20         graph.insertEdge(0, 1);
21         graph.insertEdge(1, 2);
22         graph.insertEdge(2, 3);
23         graph.insertEdge(3, 0);//插入四条边,形成连通图
24         System.out.println("深度优先遍历:");
25         graph.dfs(0, visit);
26 //        System.out.println();
27         System.out.println(visit.toString());
28         System.out.println("广度优先遍历:");
29         visit = new Visit();
30         graph.bfs(0, visit);
31         System.out.println(visit.toString());
32 
33     }
34 
35 }

原文地址:https://www.cnblogs.com/luckygxf/p/4084951.html