圖-圖的表示、搜索算法及其Java實現

1.圖的表示方法

圖:G=(V,E),V表明節點,E表明邊。java

圖有兩種表示方法:鄰接鏈表和鄰接矩陣算法

鄰接鏈表由於在表示稀疏圖(邊的條數|E|遠遠小於|V|²的圖)時很是緊湊而成爲一般的選擇。ide

若是須要快速判斷任意兩個節點之間是否有邊相連,可能也須要使用鄰接矩陣表示法。測試

鄰接鏈表表示法的魯棒性很高,能夠對其進行簡單修改來支持許多其餘的圖變種。ui

鄰接鏈表的一個潛在缺陷是沒法快速判斷一條邊是不是圖中地一條邊。鄰接矩陣則克服了這個缺陷,但付出的代價是更大的存儲空間消耗。this

 

——摘自《算法導論》spa

(1)無向圖的兩種表示

(2)有向圖的兩種表示

2.圖的搜索算法

圖的搜索算法即:廣度優先搜索和深度優先搜索3d

相信這兩種搜索算法的基本概念根據名字就可窺得一二,很少說,直接上例子。code

 

如上有向圖,建立三個類:blog

  • 點Vertex:包括點的名稱(String)和訪問標誌(boolean)。
  • 邊Edge:包括前驅點(Vertex)和後繼點(Vertex)。
  • 圖Graph:包括點集合(ArrayList<Vertex>)和邊集合(ArrayList<Edge>)。

如下是構建好的圖信息以及點遍歷結果。

 如下是Java源碼。BFS輔以隊列以非遞歸方法完成,DFS以遞歸方法完成。註釋得很詳細,我就很少解釋了@(^<>^)@。

  1 import java.util.ArrayList;
  2 import java.util.Iterator;
  3 import java.util.LinkedList;
  4 import java.util.Queue;
  5 
  6 class Graph{
  7     ArrayList<Vertex> vertexs=new ArrayList<Vertex>();
  8     ArrayList<Edge> edges=new ArrayList<Edge>();
  9     
 10     public void addVertex(Vertex vertex) {
 11         vertexs.add(vertex);
 12     }
 13     
 14     public void addEdge(Edge edge) {
 15         edges.add(edge);
 16     }
 17 }
 18 
 19 //頂點類
 20 class Vertex{
 21     String name;
 22     boolean visited=false;     //標記該點是否被查看-廣度優先專用
 23     boolean visited2=false;     //標記該點是否被查看-深度優先專用
 24     
 25     public Vertex(String name) {
 26         this.name=name;
 27     }
 28 
 29     @Override
 30     public String toString() {
 31         return "[" + name + "]";
 32     }
 33 }
 34 //邊類 有向圖
 35 class Edge{
 36     Vertex start;
 37     Vertex end;
 38     
 39     public Edge(Vertex start,Vertex end) {
 40         this.start=start;
 41         this.end=end;
 42     }
 43 
 44     @Override
 45     public String toString() {
 46         return "(" + start + "," + end + ")";
 47     }
 48 }
 49 
 50 public class SearchGraph {    
 51     //廣度優先 非遞歸
 52     static void BFS(Graph graph) {
 53         ArrayList<Vertex> vertexs=graph.vertexs;
 54         ArrayList<Edge> edges=graph.edges;
 55         Queue<Vertex> queue = new LinkedList<Vertex>();   //建立隊列
 56         
 57         queue.add(vertexs.get(0));    //頂節點放入隊列
 58         vertexs.get(0).visited=true;      //頂節點設爲已閱
 59         System.out.print(vertexs.get(0));
 60         
 61         while(!queue.isEmpty()) {
 62             Vertex vertex=queue.remove();
 63             for(Edge edge:edges) {
 64                 if(edge.start.equals(vertex)&&edge.end.visited==false) {
 65                     queue.add(edge.end);
 66                     edge.end.visited=true;
 67                     System.out.print(edge.end);
 68                 }
 69             }
 70         }
 71         
 72     }
 73     
 74     //深度優先 遞歸
 75     static void DFS(Graph graph,Vertex vertex) {  //參數:圖、點信息
 76         System.out.print(vertex);
 77         vertex.visited2=true;
 78         
 79         for(Edge edge:graph.edges) {
 80             if(edge.start.equals(vertex)&&edge.end.visited2==false) {
 81                 DFS(graph,edge.end);
 82             }
 83         }
 84     }
 85     
 86     public static void main(String[] args) {
 87         // TODO Auto-generated method stub
 88         
 89         //構造有向圖
 90         Graph graph=new Graph();
 91         Vertex v0=new Vertex("v0");
 92         Vertex v1=new Vertex("v1");
 93         Vertex v2=new Vertex("v2");
 94         Vertex v3=new Vertex("v3");
 95         Vertex v4=new Vertex("v4");
 96         Vertex v5=new Vertex("v5");
 97         Vertex v6=new Vertex("v6");
 98         graph.addVertex(v0);
 99         graph.addVertex(v1);
100         graph.addVertex(v2);
101         graph.addVertex(v3);
102         graph.addVertex(v4);
103         graph.addVertex(v5);
104         graph.addVertex(v6);
105         Edge e0=new Edge(v0,v1);
106         Edge e1=new Edge(v0,v2);
107         Edge e2=new Edge(v0,v3);
108         Edge e3=new Edge(v1,v4);
109         Edge e4=new Edge(v1,v5);
110         Edge e5=new Edge(v2,v4);
111         Edge e6=new Edge(v3,v5);
112         Edge e7=new Edge(v4,v6);
113         Edge e8=new Edge(v5,v6);
114         graph.addEdge(e0);
115         graph.addEdge(e1);
116         graph.addEdge(e2);
117         graph.addEdge(e3);
118         graph.addEdge(e4);
119         graph.addEdge(e5);
120         graph.addEdge(e6);
121         graph.addEdge(e7);
122         graph.addEdge(e8);
123         //構造有向圖
124         
125         //測試圖建立結果
126         ArrayList<Vertex> vertexs=graph.vertexs;
127         ArrayList<Edge> edges=graph.edges;
128         Iterator iVertex=vertexs.iterator();
129         Iterator iEdge=edges.iterator();
130         System.out.println("點集合:");
131         while(iVertex.hasNext()) {
132             System.out.print(iVertex.next());
133         }
134         System.out.println();
135         System.out.println("邊集合:");
136         while(iEdge.hasNext()) {
137             System.out.print(iEdge.next());
138         }
139         //測試圖建立結果
140         
141         //遍歷
142         System.out.println("");
143         System.out.println("廣度優先遍歷:");
144         BFS(graph);
145         System.out.println("");
146         System.out.println("深度優先遍歷:");
147         DFS(graph,v0);
148         //遍歷
149     }
150 
151 }
相關文章
相關標籤/搜索