一文掌握Hierholzer算法

Hierholzer算法的精髓是当每次访问一条边的时候,删除这条边,当遍历完一个节点所连的所有节点后,才将该节点入栈,最后将栈中的节点反转,即可得到欧拉路径

    public void printCircuit(List<List<Integer>> adj) {
        //edgeCount记录记录有向图的边的条数,从当前节点v出发
        Map<Integer, Integer> edgeCount = new HashMap<>();
        for (int i = 0; i < adj.size(); i++) {
            edgeCount.put(i, adj.get(i).size());
        }
        if (edgeCount.isEmpty()) return;
        //栈用来记录节点
        Stack<Integer> currPath = new Stack<>();
        //存储欧拉回路
        List<Integer> circuit = new ArrayList<>();
        //可以从任何点出发
        currPath.push(0);
        int currV = 0; //当前的节点
        while (!currPath.isEmpty()) {
            //当前还有没有走完的边
            if (edgeCount.containsKey(currV) && edgeCount.get(currV) > 0) {
                currPath.push(currV);//存储当前节点
                int nextV = adj.get(currV).get(adj.get(currV).size() - 1);//找下个节点  也可以remove 掉第一个 0
                //删边与删除节点
                edgeCount.put(currV, edgeCount.get(currV) - 1);
                adj.get(currV).remove(adj.get(currV).size() - 1);
                //移动到下一个节点
                currV = nextV;
            } else {//回溯找circuit
                circuit.add(currV);
                currV = currPath.get(currPath.size() - 1);
                currPath.pop();
            }
        }
        for (int i = circuit.size() - 1; i >= 0; i--) {
            System.out.print(circuit.get(i));
            if (i != 0) System.out.print(" -> ");
        }
//        System.out.print("\n");
    }

测试类

public void testOne() {
    //adj1
    List<List<Integer>> adj1 = new ArrayList<>();
    adj1.add(new ArrayList<Integer>() {{
        add(1);
    }});
    adj1.add(new ArrayList<Integer>() {{
        add(2);
    }});
    adj1.add(new ArrayList<Integer>() {{
        add(0);
    }});
    printCircuit(adj1);
    //adj2
    List<List<Integer>> adj2 = new ArrayList<>();
    adj2.add(new ArrayList<Integer>() {{
        add(1);
        add(6);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(2);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(0);
        add(3);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(4);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(2);
        add(5);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(0);
    }});
    adj2.add(new ArrayList<Integer>() {{
        add(4);
    }});
    printCircuit(adj2);
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值