拓扑排序
定义
对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列。
- 拓扑排序针对的是有向图
- 不可以有环
- 可以用一定的规则进行遍历整个图(遍历所有入度为0的点)
代码
拓扑排序的代码其实很简单。
// 得到入度
public int getIn(int n){
int res=0;
for(int i=0;i< graph.length;i++){
if(graph[i][n]!=0){
res+=1;
}
}
return res;
}
public boolean isTopology(){
Stack<Integer> stack = new Stack<>();
// init
for(int i=0;i< graph.length;i++){
if(getIn(i)==0){ // 如果入度为0,我们加入栈
stack.push(i);
}
}
int visitedLen = 0;
while (!stack.isEmpty()){
int val = stack.pop();// 出栈
System.out.println(names[val]);// 遍历的点
for(int j=0;j< graph.length;j++){
if(graph[val][j]!=0){
graph[val][j] = 0; // 将遍历的点的出度设为0;
if(getIn(j)==0){ //看他的出度是否有入度为0的点
stack.push(j);
}
}
}
visitedLen++;
}
return visitedLen==graph.length;
}
后序
也可以用队列,拓扑排序的顺序是允许有一定的不同。
链表
class AoeNode{
String name;
ArcAoeNode firstArc;
public AoeNode(String name) {
this.name = name;
}
}
class ArcAoeNode{
int nextNode;
int weight;
ArcAoeNode nextArc;
public ArcAoeNode(int nextNode, int weight) {
this.nextNode = nextNode;
this.weight = weight;
}
}
public class CriticalPath {
List<AoeNode> list;
public CriticalPath(List<AoeNode> list) {
this.list = list;
}
public int getin(int nodeIndex){
int countIn=0;
for(AoeNode aoe:list){
ArcAoeNode arcAoeNode = aoe.firstArc;
while (arcAoeNode!=null){
if(arcAoeNode.nextNode == nodeIndex ){
countIn+=1;
}
arcAoeNode = arcAoeNode.nextArc;
}
}
return countIn;
}
// topologic
public boolean topologic(){
Queue<Integer> queue = new LinkedList<>();
int[] book = new int[list.size()];
// init
for(int i=0;i<list.size();i++){
book[i] = getin(i);
if(book[i]==0){
queue.offer(i);
}
}
int visitLen = 0;
while (!queue.isEmpty()){
int poll = queue.poll();
System.out.println(list.get(poll).name+"---");
ArcAoeNode arcAoeNode = list.get(poll).firstArc;
while (arcAoeNode!=null){
int node = arcAoeNode.nextNode;
book[node]--;
if(book[node]==0){
queue.offer(node);
}
arcAoeNode = arcAoeNode.nextArc;
}
}
return visitLen==list.size();
}
}
class testCriticalPath{
public static void main(String[] args) {
List<AoeNode> list = new ArrayList<>();
// 加人点
for(int i=0;i<10;i++){
list.add(new AoeNode("V"+i));
}
// 加入边
// v0
AoeNode aoeNode = list.get(0);
aoeNode.firstArc = new ArcAoeNode(1,3);
aoeNode.firstArc.nextArc = new ArcAoeNode(2,4);
// v1
aoeNode = list.get(1);
aoeNode.firstArc = new ArcAoeNode(3,5);
aoeNode.firstArc.nextArc = new ArcAoeNode(4,6);
// v2
aoeNode = list.get(2);
aoeNode.firstArc = new ArcAoeNode(3,8);
aoeNode.firstArc.nextArc = new ArcAoeNode(5,7);
// v3
aoeNode = list.get(3);
aoeNode.firstArc = new ArcAoeNode(4,3);
// v4
aoeNode = list.get(3);
aoeNode.firstArc = new ArcAoeNode(6,9);
aoeNode.firstArc.nextArc = new ArcAoeNode(7,4);
// v5
aoeNode = list.get(5);
aoeNode.firstArc = new ArcAoeNode(7,6);
// v6
aoeNode = list.get(6);
aoeNode.firstArc = new ArcAoeNode(9,2);
// v7
aoeNode = list.get(7);
aoeNode.firstArc = new ArcAoeNode(8,5);
// v8
aoeNode = list.get(8);
aoeNode.firstArc = new ArcAoeNode(9,3);
// 图的完成
CriticalPath criticalPath = new CriticalPath(list);
System.out.println(criticalPath.topologic());
}
}
浙公网安备 33010602011771号