图论基本算法的实现


package util;

import java.util.LinkedList;
import java.util.*;

/**
 * @Author lyr
 * @create 2020/7/25 13:44
 */
public class Graph {
    private class Node {
        private String label;

        public Node(String label) {
            this.label = label;
        }

        @Override
        public String toString() {
            return "{ " + label + " }";
        }
    }

    Map<String, Node> nodes = new HashMap<>();
    Map<Node, List<Node>> adjacencyList = new HashMap<>();

    public void addNode(String label) {
        var node = new Node(label);
        nodes.putIfAbsent(label, node);
        adjacencyList.putIfAbsent(node, new LinkedList<>());
    }

    public void addEdge(String from, String to) {
        var fromNode = nodes.get(from);
        var toNode = nodes.get(to);
        if (fromNode == null) {
            throw new IllegalStateException();
        }
        if (toNode == null) {
            throw new IllegalStateException();
        }
        adjacencyList.get(fromNode).add(toNode);

    }

    public void print() {
        for (var entry : adjacencyList.entrySet()) {
            var target = entry.getValue();
            if (target.isEmpty() == false) {
                System.out.println(entry.getKey() + " -> " + entry.getValue());
            }
        }
    }

    public void removeNode(String label) {
        var node = nodes.get(label);
        if (node == null) return;
        for (var entry : adjacencyList.entrySet()) {
            //移除所有的边中包含 node的
            entry.getValue().remove(node);
        }
        //移除自己的
        adjacencyList.remove(node);
        nodes.remove(label);
    }

    public void removeEdge(String from, String to) {
        var fromNode = nodes.get(from);
        var toNode = nodes.get(to);

        if (fromNode == null || toNode == null) {
            return;
        }
        adjacencyList.get(fromNode).remove(toNode);
        adjacencyList.get(toNode).remove(fromNode);

    }

    public void dfs(String root) {
        var node = nodes.get(root);
        if (node == null) return;

        dfs(node, new HashSet<>());
    }

    private void dfs(Node root, Set<Node> record) {
        System.out.println(root);
        record.add(root);

        for (var node : adjacencyList.get(root)) {
            if (record.contains(node) == false) {
                dfs(node, record);
            }
        }
    }

    public void dfs2(String root) {
        var node = nodes.get(root);
        if (node == null) {
            return;
        }
        Set<Node> visited = new HashSet<>();
        Deque<Node> s = new LinkedList<>();
        s.push(node);
        while (s.isEmpty() == false) {
            var cur = s.pop();
            if (visited.contains(cur)) {
                continue;
            }
            System.out.println(cur);
            visited.add(cur);
            for (var neighbor : adjacencyList.get(cur)) {
                if (!visited.contains(neighbor)) {
                    s.push(neighbor);
                }
            }
        }


    }

    public void bfs(String root) {
        var node = nodes.get(root);
        if (root == null) {
            return;
        }
        Set<Node> visited = new HashSet<>();
        Queue<Node> q = new ArrayDeque<>();
        q.add(node);
        while (q.isEmpty() == false) {
            var cur = q.remove();
            if (visited.contains(cur)) {
                continue;
            }
            System.out.println(cur);
            visited.add(cur);
            for (var neighbour : adjacencyList.get(cur)) {
                if(visited.contains(neighbour) == false) {
                    //进入队列,下一次会继续扩散
                    q.add(neighbour);
                    // System.out.println(neighbour);
                }
            }
        }
    }

    public boolean hasCycle() {
        Set<Node> all = new HashSet<>();
        all.addAll(nodes.values());
        Set<Node> visiting = new HashSet<>();
        Set<Node> visited = new HashSet<>();
        var it = all.iterator();
        while (!all.isEmpty()) {
            var cur = it.next();
            if(hasCycle(cur,all,visiting,visited)) {
                return  true;
            }
        }
        return false;
    }

    private boolean hasCycle(Node node,Set<Node> all,Set<Node> visiting,
                             Set<Node> visited) {
        all.remove(node);
        visiting.add(node);
        for (var neighbour: adjacencyList.get(node)) {
            if( visited.contains(neighbour)) {
                continue;
            }
            if(visiting.contains(neighbour)) {
                return  true;
            }
            var result = hasCycle(neighbour,all,visiting,visited);
            if(result) {
                //如果有环,退出检测
                return true;
            }
        }
        visited.add(node);
        visiting.add(node);
        return false;
    }


}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值