从一个顶点出发指向另一个顶点,以箭头的方式。
出度:某个顶点指出的边的个数称为该顶点的出度
入度:指向某个顶点的边的个数称为该顶点的入度
有向路径:由一系列顶点组成,对于其中的每个顶点都存在一条有向边,从它指向序列中的下一个顶点。
有向环:一条至少含有一条边,且起点和终点相同的有向路径。
拓扑排序:
如果我们要使用拓扑排序解决优先级问题,首先得保证图中没有环的存在。
代码:
package com.chenqing.test.digraph;
/**
* @author 陈沁
* 检测有向图中是否有环
*/
public class DirectCircle {
private boolean[] marked;
private boolean isCycle;
private boolean[] isStack;
public DirectCircle(Digraph digraph) {
this.marked = new boolean[digraph.getV()];
this.isCycle = false;
this.isStack = new boolean[digraph.getV()];
for (int v = 0; v < digraph.getV(); v++) {
if (!marked[v]) {
dfs(digraph, v);
}
}
}
private void dfs(Digraph digraph, int s) {
this.marked[s] = true;
this.isStack[s] = true;
for (Integer v :
digraph.getTable(s)) {
if (!marked[v]) {
dfs(digraph, v);
}
if(isStack[v]){
isCycle = true;
return;
}
}
this.isStack[s] = false;
}
public boolean isCycle() {
return isCycle;
}
}
基于深度优先的顶点排序:
package com.chenqing.test.digraph;
import com.chenqing.test.linearList.stack.Stack;
/**
* @author 陈沁
* 基于深度优先的顶点排序
*/
public class DepthFirstOrder {
private boolean[] marked;
private Stack<Integer> vStack;
public DepthFirstOrder(Digraph digraph) {
this.marked = new boolean[digraph.getV()];
this.vStack = new Stack<Integer>();
for (int i = 0; i < digraph.getV(); i++) {
if(!marked[i]){
dfs(digraph, i);
}
}
}
private void dfs(Digraph digraph, int s){
this.marked[s] = true;
for (Integer i : digraph.getTable(s)) {
if(!marked[i]){
dfs(digraph, i);
}
}
vStack.push(s);
}
public Stack<Integer> getVStack(){
return vStack;
}
}