Java算法求有向无环图拓扑排序

图存储方式:
邻接表方式存储

class Node{
    int visited = 0; // 是否被访问
    int d = 0; // 初次遍历时间戳
    int f = 0; // 最终遍历时间戳
    LinkedList<Integer> linkNodes = null;
    public Node(){
        linkNodes = new LinkedList<>();
    }
}

以上代码为一个节点的数据结构,最终用一个数组储存所有节点
求解: 深度优先算法
在使用dfs进行遍历时节点要记录两个索引,即以上代码中的 d 和 f。d 的值表示该节点第一次被遍历到时的时间戳,f 的值表示再次回溯到该节点的时间戳。该时间戳 f 与 d 共享,每遍历一个节点加一。
最终的拓扑排序以 f 的值降序排序。

java代码:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * 求有向无环图的拓扑结构
 */
public class TopoLogical {
    static int time = 0; //记录遍历次序
    static ArrayList<Integer> topology; // 记录拓扑顺序的反序
    static Node[] nodes;
    public static void main(String[] args){
        /**
         * 输入方式:
         * 第一行输入节点的个数n
         * 后面n行输入第n个节点(从0开始数)链接的子节点,没有子节点则直接换行
         */
        Scanner input = new Scanner(System.in);
        int n = input.nextInt();
        nodes = new Node[n];
        topology = new ArrayList<>();
        for(int i = 0; i < n; ++i){
            nodes[i] = new Node();
        }

        input.nextLine();

        for(int i = 0; i < n; ++i){
            String line = input.nextLine();
            if(!line.equals("")){
                String[] tempIntStr = line.split(" ");
                for(int j = 0; j < tempIntStr.length; ++j){
                    nodes[i].linkNodes.add(Integer.parseInt(tempIntStr[j]));
                }
            }
        }
        for(int i=0;i<nodes.length;i++){
            dfs(nodes[i], i);
        }
        System.out.print("拓扑顺序: ");
        for(int i=topology.size()-1;i>=0;i--){
            System.out.print(topology.get(i) + " ");
        }
    }
    static void dfs(Node node,int index){
        if(node.visited==1 || node==null)
            return;
        time ++;
        node.d = time;
        node.visited = 1;
        for(int i : node.linkNodes){
            Node current = nodes[i];
            if(current.visited == 0)
                dfs(current, i);
        }
        topology.add(index);
        time ++;
        node.f = time;
    }

}

class Node{
    int visited = 0; // 是否被访问
    int d = 0; // 遍历次序
    int f = 0; // 最终遍历次序
    LinkedList<Integer> linkNodes = null;
    public Node(){
        linkNodes = new LinkedList<>();
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值