图的表示及搜索算法

1.图的表示方法

图:G=(V,E),V代表节点,E代表边。

图有两种表示方法:邻接链表和邻接矩阵

邻接链表因为在表示稀疏图(边的条数|E|远远小于|V|²的图)时非常紧凑而成为通常的选择。

如果需要快速判断任意两个节点之间是否有边相连,可能也需要使用邻接矩阵表示法。

邻接链表表示法的鲁棒性很高,可以对其进行简单修改来支持许多其他的图变种。

邻接链表的一个潜在缺陷是无法快速判断一条边是否是图中地一条边。邻接矩阵则克服了这个缺陷,但付出的代价是更大的存储空间消耗。

——摘自《算法导论》

(1)无向图的两种表示

(2)有向图的两种表示

2.图的搜索算法

图的搜索算法即:广度优先搜索和深度优先搜索

相信这两种搜索算法的基本概念根据名字就可窥得一二,不多说,直接上例子。

如上有向图,创建三个类:

  • 点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 }

猜你喜欢

转载自www.cnblogs.com/StrayLesley/p/10739624.html