算法笔记14:有向图
有向图
无向图见算法笔记13:无向图
有向图和无向图的区别
在无向图中,连接是没有方向的,连接v-w意味着可以从顶点v到顶点w,但是有向图的连接是有方向的,连接v→w意味着只能从v到达w,而不能从w到v。有向图可以表示很多关系:食物链中的捕食关系、论文的引用、程序的引用等。在有向图中两个顶点之间的关系有四种:v不能到w,w也不能到v;v能到w,w不能到v;w能到v,v不能到w;v能到w,w也能到v;
在有向图中,从顶点v指出的边的数目是顶点v的出度,指向v的边的数目是顶点v的入度。
有向图的实现
有向图的数据结构和无向图一样依然采用邻接表,唯一的区别就是addEdage(v,w)中只改变adj[v]。
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
/**
* 有向图
* @author XY
*
*/
public class DirectedGraph {
private ArrayList<Integer>[] adj;
private int V;
private int E;
public DirectedGraph(int v) {
this.V = v;
this.adj = (ArrayList<Integer>[]) new ArrayList[v];
for (int i = 0; i < adj.length; i++) {
adj[i] = new ArrayList<Integer>();
}
}
public DirectedGraph(Scanner scanner) {
this(scanner.nextInt());
int e = scanner.nextInt();
for (int i = 0; i < e; i++) {
int v = scanner.nextInt();
int w = scanner.nextInt();
addEdage(v, w);
}
}
public DirectedGraph reverseGraph(){
//有向图的反向图
DirectedGraph reverse=new DirectedGraph(this.V);
for (int i = 0; i < this.V; i++) {
for (int j :adj[i]) {
reverse.addEdage(j, i);
}
}
return reverse;
}
public void addEdage(int v, int w) {
adj[v].add(w);//和无向图的区别
this.E++;
}
public Iterable<Integer> adj(int v) {
return this.adj[v];
}
public int V() {
return this.V;
}
public int E() {
return this.E;
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("V: " + this.V + "\n");
sb.append("E: " + this.E + "\n");
for (int i = 0; i < this.V; i++) {
sb.append(i + ": ");
for (int x : adj[i])
sb.append(x + " ");
sb.append("\n");
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
//测试用例
DirectedGraph dg = new DirectedGraph(new Scanner(new File("e:"
+ File.separator + "dgraph.txt")));
System.out.println(dg);
}
}
有向符号图
import java.io.File;
import java.util.HashMap;
import java.util.Scanner;
/**
* 有向符号图,和无向图的符号图完全一样
* @author XY
*
*/
public class SymbolDirectedGraph {
private DirectedGraph dgraph;
private HashMap<String, Integer> index;
private String[] name;
public SymbolDirectedGraph(File file, String delmin) throws Exception {
Scanner scan = new Scanner(file);
index = new HashMap<String, Integer>();
int count = 0;
while (scan.hasNextLine()) {
String[] temp = scan.nextLine().split(delmin);
for (int i = 0; i < temp.length; i++)
if (!index.containsKey(temp[i]))
index.put(temp[i], count++);
}
this.dgraph = new DirectedGraph(count