您的位置:首页 > 理论基础 > 数据结构算法

拓扑排序-bfs-广度优先搜索

2017-10-12 16:49 393 查看

breadth-first search

package com.ygy.test.sort;

import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
* Created by guoyao on 2017/10/11.
*/

//拓扑排序
public class TopologicalSorting {

//定义顶点信息
private static class Vertex {

@Getter @Setter
private  int indegree;  //入度

@Getter @Setter
private String name ;  //顶点信息

//广度优先搜索新增字段
@Getter @Setter
private int deepPath = Integer.MIN_VALUE ;  //路径深度 初始化为最小

@Getter @Setter
private Boolean isKnown = false ;   //路口是否已探  初始化为false

@Getter @Setter
private Vertex preShortVertex ;

public boolean isKnown() {
return isKnown ;
}

public Vertex(String name) {
this.name=name;
indegree = 0 ;   //初始入度为0
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Vertex vertex=(Vertex) o;

return name.equals(vertex.name);
}

@Override
public int hashCode() {
return name.hashCode();
}
}

//定义拓扑关系图
private static class TopoGraph {

public Map<Vertex, Set<Vertex>> relMap=new HashMap<>();  //顶点与节点关系

public Set<Vertex> vertices=new HashSet<>();  //所有节点信息

//添加顶点关系图
public boolean addRelVertex(Vertex start, Vertex end) {

//根据name判断重复
vertices.add(start);
vertices.add(end);

Set<Vertex> adjcents=relMap.get(start);  //相邻节点信息
if (CollectionUtils.isEmpty(adjcents)) {
adjcents = new HashSet<>();
}

if (adjcents.contains(end)) {
return false;
}

adjcents.add(end);
int indegree=end.getIndegree();
end.setIndegree(++indegree);    //入度+1
relMap.put(start, adjcents);
return true;
}
}

public static List<Vertex> bfs_sort(TopoGraph topoGraph, Vertex firstRoot) {
Queue<Vertex> knownQueue=new LinkedList<>();
List<Vertex> resultList=new ArrayList<>();
firstRoot.setDeepPath(0);  //设置深度为0
firstRoot.setIsKnown(true);  //设置为已探知
knownQueue.add(firstRoot);
while (!knownQueue.isEmpty()) {

Vertex knownVertex=knownQueue.poll();
resultList.add(knownVertex);
Set<Vertex> adjacents=topoGraph.relMap.get(knownVertex);  //相邻节点信息

if (!CollectionUtils.isEmpty(adjacents)) {
for (Vertex adj : adjacents) {
if (!adj.isKnown()) {
//深度+1 表明为已探知,指定上一个节点
adj.setDeepPath(knownVertex.getDeepPath() + 1);
adj.setIsKnown(true);
adj.setPreShortVertex(knownVertex);
knownQueue.add(adj);
}
}
}
}
return resultList;
}

public static void printShortPath(List<Vertex> list) {

if (CollectionUtils.isEmpty(list)) {
return;
}
for (Vertex vertex : list) {
int count = 0 ;
while (vertex != null) {
if (count != 0) {
System.out.print("<----");
}
System.out.print(vertex.getName()+ ":"+ vertex.getDeepPath());
vertex = vertex.preShortVertex;
count ++ ;
}
System.out.println();
}
}

4000
if (count != resultList.size()) {
throw new RuntimeException(" 闭环");
}
return resultList;

}

public static void main(String[] args) throws Exception  {

Vertex vertexA=new Vertex("A");
Vertex vertexB=new Vertex("B");
Vertex vertexC=new Vertex("C");
Vertex vertexD=new Vertex("D");
Vertex vertexE=new Vertex("E");
TopoGraph topoGraph=new TopoGraph();
topoGraph.addRelVertex(vertexA, vertexB);
topoGraph.addRelVertex(vertexA, vertexC);
topoGraph.addRelVertex(vertexC, vertexD);
topoGraph.addRelVertex(vertexB, vertexD);
topoGraph.addRelVertex(vertexB, vertexE);
topoGraph.addRelVertex(vertexD, vertexE);

//广度优先搜索
List<Vertex> vertices=bfs_sort(topoGraph, vertexA);
printShortPath(vertices);
}
//打印结果   到达 a b c d e 的最短路径
//A:0
//B:1<----A:0
//C:1<----A:0
//D:2<----B:1<----A:0
//E:2<----B:1<----A:0

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息