图的拓扑排序(java版本)
- 抽象出一种图的结构,经典的图结构
一种通用的图的定义
Node
public class Node {
int out;
int in;
int value;
ArrayList<Node> nexts;
ArrayList<Edge> edges;
public Node(int value){
this.out = 0;
this.in = 0;
this.value = value;
this.nexts = new ArrayList<>();
this.edges = new ArrayList<>();
}
}
Graph
public class Graph {
Map<Integer, Node> nodes;
Set<Edge> edges;
public Graph(){
nodes = new HashMap<>();
edges = new HashSet<>();
}
}
Edge
public class Edge {
public int weight;
public Node from;
public Node to;
public Edge(int weight, Node from, Node to) {
this.weight = weight;
this.from = from;
this.to = to;
}
}
图的宽度优先遍历
GraphBFS
public class GraphBFS {
public void graphBFS(Node start) {
if (start == null) {
return;
}
Queue<Node> queue = new LinkedList<>();
HashSet<Node> set = new HashSet<>();
queue.add(start);
set.add(start);
while (!queue.isEmpty()) {
Node cur = queue.poll();
System.out.println(cur.value);
for (Node next : cur.nexts) {
if (!set.contains(next)) {
set.add(next);
queue.add(next);
}
}
}
}
}
图的深度优先遍历
一条路没走完就走到死,走到了就往上
GraphDFS
public class GraphDFS {
public void graphDFS(Node start){
if(start == null){
return;
}
Stack<Node> stack = new Stack<>();
HashSet<Node> set = new HashSet<>();
stack.add(start);
set.add(start);
while(!stack.isEmpty()){
Node cur = stack.pop();
for(Node next:cur.nexts){
if(!set.contains(next)){
stack.push(cur);
stack.push(next);
set.add(next);
System.out.println(next.value);
break;
}
}
}
}
}
1.迭代自己压栈,2.栈里面放着是整条路径,3.加入就打印(处理数据)
图的拓扑排序算法
- 通用拓扑排序,一般是根据入度来计算
TopologySort
public class TopologySort {
// directed graph and no loop
public static List<Node> sortedTopology(Graph graph) {
HashMap<Node, Integer> imMap = new HashMap<>();
//入度为零的队列, 优先处理
Queue<Node> zeroInQueue = new LinkedList<>();
for(Node node : graph.nodes.values()){
imMap.put(node, node.in);
if(node.in == 0){
zeroInQueue.add(node);
}
}
ArrayList<Node> result = new ArrayList<>();
while(!zeroInQueue.isEmpty()){
Node cur = zeroInQueue.poll();
result.add(cur);
for(Node next:cur.nexts){
imMap.put(next, imMap.get(next) - 1);
if(imMap.get(next) == 0){
zeroInQueue.add(next);
}
}
}
return result;
}
}
- BFS拓扑排序
TopologicalOrderBFS
public class TopologicalOrderBFS {
public static class DirectedGraphNode{
public int label;
public ArrayList<DirectedGraphNode> neighbors;
public DirectedGraphNode(int x){
this.label = x;
neighbors = new ArrayList<DirectedGraphNode>();
}
}
public static ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph){
HashMap<DirectedGraphNode, Integer> indegreeMap = new HashMap<>();
for(DirectedGraphNode cur : graph){
indegreeMap.put(cur, 0);
}
for(DirectedGraphNode cur : graph){
for(DirectedGraphNode next: cur.neighbors){
indegreeMap.put(next, indegreeMap.get(next) + 1);
}
}
Queue<DirectedGraphNode> queue = new LinkedList<>();
//入度为0加如队列
for(DirectedGraphNode cur : indegreeMap.keySet()){
if(indegreeMap.get(cur) == 0){
queue.add(cur);
}
}
ArrayList<DirectedGraphNode> res = new ArrayList<>();
while(!queue.isEmpty()){
DirectedGraphNode cur = queue.poll();
res.add(cur);
for(DirectedGraphNode next : cur.neighbors){
indegreeMap.put(next, indegreeMap.get(next) - 1);
//入度为0 加入队列
if(indegreeMap.get(next) == 0){
queue.offer(next);
}
}
}
return res;
}
}
- DFS 拓扑排序
TopologicalOrderDFS
public class TopologicalOrderDFS {
public static class DirectedGraphNode {
public int label;
public ArrayList<DirectedGraphNode> neighbors;
public DirectedGraphNode(int x) {
this.label = x;
}
}
public static class Record {
public DirectedGraphNode node;
public int deep;
public Record(DirectedGraphNode node, int deep) {
this.node = node;
this.deep = deep;
}
}
public static class MyComparator implements Comparator<Record> {
@Override
public int compare(Record o1, Record o2) {
return o2.deep - o1.deep;
}
}
public static ArrayList<DirectedGraphNode> topSort(ArrayList<DirectedGraphNode> graph) {
HashMap<DirectedGraphNode, Record> order = new HashMap<>();
for (DirectedGraphNode cur : graph) {
f(cur, order);
}
//存储所有的node节点
ArrayList<Record> records = new ArrayList<>();
for (Record r : order.values()) {
records.add(r);
}
// 排序?
records.sort(new MyComparator());
records.sort(new MyComparator());
ArrayList<DirectedGraphNode> directedGraphNodes = new ArrayList<>();
for (Record r : records) {
directedGraphNodes.add(r.node);
}
return directedGraphNodes;
}
//计算每个node的深度
public static Record f(DirectedGraphNode cur, HashMap<DirectedGraphNode, Record> order) {
if (order.containsKey(cur)) {
return order.get(cur);
}
int follow = 0;
for (DirectedGraphNode next : cur.neighbors) {
follow = Math.max(follow, f(next, order).deep);
}
Record ans = new Record(cur, follow + 1);
order.put(cur, ans);
return ans;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构