算法基础部分-图

public class Drawing {
    public HashMap<Integer, Node> nodes;//Drawing的点集
    public HashSet<Edge> edges;//Drawing的边集

    public Drawing() {
        nodes = new HashMap<>();
        edges = new HashSet<>();
    }


    public static class Node {
        public int value; //点的编号
        public int in; //入度
        public int out;//出度
        public ArrayList<Node> nexts; //从自己出发相邻的点
        public ArrayList<Edge> edges;//以及自己的边

        public Node(int value) {
            this.value = value;
            in = 0;
            out = 0;
            nexts = new ArrayList<>();
            edges = new ArrayList<>();
        }
    }

    //边
    public static class Edge {
        public int weight; // 权重 表示距离
        public Node from;//有向边   from A to b  从哪个节点出来到哪个节点去
        public Node to;//

        public Edge(int weight, Node from, Node to) {
            this.weight = weight;
            this.from = from;
            this.to = to;
        }
    }


    //matrux 所有的边
    //N*3的矩阵 将二维数组转换为Drawing
    //[weight,from节点上面的值,to节点上面的值]
    public static Drawing createGraph(Integer[][] matrix) {
        Drawing graph = new Drawing();
        for (int i = 0; i < matrix.length; i++) {
            Integer from = matrix[i][0];
            Integer to = matrix[i][1];
            Integer weight = matrix[i][2];
            if (!graph.nodes.containsKey(from)) {
                graph.nodes.put(from, new Node(from));
            }
            if (!graph.nodes.containsKey(to)) {
                graph.nodes.put(to, new Node(to));
            }
            Node fromNode = graph.nodes.get(from);
            Node toNode = graph.nodes.get(to);
            Edge newEdg = new Edge(weight, fromNode, toNode);
            fromNode.nexts.add(toNode);
            fromNode.out++;
            toNode.in++;
            fromNode.edges.add(newEdg);
            graph.edges.add(newEdg);
        }
        return graph;
    }

    //宽度优先遍历
    public static void bfs(Node node) {
        if (node == null) {
            return;
        }
        Queue<Node> queue = new LinkedList<Node>();
        HashSet<Node> set = new HashSet<Node>();
        queue.add(node);
        set.add(node);
        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);
                }
            }
        }
    }

    //    深度优先遍历
    public static void dfs(Node node) {
        if (node == null) {
            return;
        }
        Stack<Node> stack = new Stack<>();
        HashSet<Node> set = new HashSet<Node>();
        stack.add(node);
        set.add(node);
        System.out.println(node.value);
        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;
                }
            }
        }
    }

    //拓扑排序
    public static List<Node> sortedTopology(Drawing graph) {
        //key: 某一个node
        //value: 剩余的入度
        HashMap<Node, Integer> inMap = new HashMap<>();
        //入度为0的点,才能进这个队列
        Queue<Node> zeroInQueue = new LinkedList<>();
        for (Node node : graph.nodes.values()) {
            inMap.put(node, node.in);
            if (node.in == 0) {
                zeroInQueue.add(node);
            }
        }
        //拓扑排序的结果依次加入result
        List<Node> result = new ArrayList<>();
        while (!zeroInQueue.isEmpty()) {
            Node cur = zeroInQueue.poll();
            result.add(cur);
            for (Node next : cur.nexts) {
                inMap.put(next, inMap.get(next) - 1);
                if (inMap.get(next) == 0) {
                    zeroInQueue.add(next);
                }
            }
        }
        return result;
    }

    //最小生成树 k算法
    public static class MySets {
        public HashMap<Node, List<Node>> setMap = new HashMap<>();

        public MySets(List<Node> nodes) {
            for (Node cur : nodes) {
                List<Node> set = new ArrayList<>();
                set.add(cur);
                setMap.put(cur, set);
            }
        }
        //from 点和to点在不在一个集合里面 是一个集合就是true 不是就是false

        public boolean isSameSet(Node from, Node to) {
            List<Node> fromSet = setMap.get(from);
            List<Node> toSet = setMap.get(to);
            return fromSet == toSet;
        }

        //合并两个集合
        public void union(Node from, Node to) {
            List<Node> fromSet = setMap.get(from);
            List<Node> toSet = setMap.get(to);
            for (Node toNode : toSet) {
                fromSet.add(toNode);
                setMap.put(toNode, fromSet);
            }
        }

        //    k算法生成最小生成树
        public static Set<Edge> kruskaLMST(Drawing graph) {
            HashMap<Integer, Node> nodes = graph.nodes;
            Collection<Node> values = nodes.values();
            List<Node> collect = values.stream().collect(Collectors.toList());
            MySets set = new MySets(collect);
            PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new Comparequeue());
            HashSet<Edge> edges = graph.edges;
            for (Edge edge : edges) {
                priorityQueue.add(edge);
            }
            Set<Edge> result = new HashSet<>();
            while (!priorityQueue.isEmpty()) {
                Edge edge = priorityQueue.poll();
                boolean sameSet = set.isSameSet(edge.from, edge.to);
                if (!sameSet) {
                    result.add(edge);
                    set.union(edge.from, edge.to);
                }
            }
            return result;
        }

        public static class Comparequeue implements Comparator<Edge> {
            @Override
            public int compare(Edge o1, Edge o2) {
                return o1.weight - o2.weight;
            }
        }
    }

    //    p算法
    public static Set<Edge> primMST(Drawing graph) {
        //解锁的边进入小根堆
        PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new MySets.Comparequeue());
        HashSet<Node> set = new HashSet<>();
        Set<Edge> result = new HashSet<>();//依次挑选的边在result里
        for (Node node : graph.nodes.values()) {//随便挑了一个点
            //node 是开始点
            if (!set.contains(node)) {
                set.add(node);
                for (Edge edge : node.edges) {//由一个点,解锁所有相连的边
                    priorityQueue.add(edge);
                }
                while (!priorityQueue.isEmpty()) {
                    Edge edge = priorityQueue.poll();//弹出解锁的边中,最小的边
                    Node toNode = edge.to;//可能的一个新的点
                    if (!set.contains(toNode)) {//不含有的时候,就是新的点
                        set.add(toNode);
                        result.add(edge);
                        for (Edge nextEdge : toNode.edges) {
                            priorityQueue.add(nextEdge);
                        }
                    }
                }
            }

        }
        return result;
    }


    //p算法
    public static void main(String[] args) {
//        Integer[] [] arr = {{0,1,5},{1,3,8},{3,0,9}};
//        Drawing graph = createGraph(arr);

        Drawing tu = new Drawing();
        HashMap<Integer, Node> nodes = new HashMap<>();
        HashSet<Edge> edges = new HashSet<>();
        Node n1 = new Node(1);
        Node n2 = new Node(2);
        Node n3 = new Node(3);
        Node n4 = new Node(4);
        Node n5 = new Node(5);
        n1.nexts.add(n2);
        n1.nexts.add(n4);
        n1.nexts.add(n3);
        n2.nexts.add(n1);
        n2.nexts.add(n3);
        n3.nexts.add(n1);
        n3.nexts.add(n2);
        n3.nexts.add(n4);
        n3.nexts.add(n5);
        n4.nexts.add(n1);
        n4.nexts.add(n3);
        n1.in = 3;
        n2.in = 2;
        n3.in = 4;
        n4.in = 2;
        n5.in = 1;
        n1.out = 3;
        n2.out = 2;
        n3.out = 4;
        n5.out = 1;
        nodes.put(1, n1);
        nodes.put(2, n2);
        nodes.put(3, n3);
        nodes.put(4, n4);
        nodes.put(5, n5);
        tu.nodes = nodes;
        Edge edge1 = new Edge(20, n1, n4);
        Edge edge2 = new Edge(1000, n1, n3);
        Edge edge3 = new Edge(30, n1, n2);
        Edge edge4 = new Edge(10, n2, n3);
        Edge edge5 = new Edge(20, n3, n5);
        edges.add(edge1);
        edges.add(edge2);
        edges.add(edge3);
        edges.add(edge4);
        edges.add(edge5);
        tu.edges = edges;

        MySets.kruskaLMST(tu);
//        List<Node> nodes1 = sortedTopology(tu);

    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值