kruskal算法

48 篇文章 0 订阅
46 篇文章 0 订阅

kruskal算法
假设两点之间的边都有权重,那么将所有点加入成图后,要求所有权重和最小
1.将所有边进行排序,由低到高
2.所有的节点都是独立的集合
3.选择从最小边开始,判断from 节点和to节点是否会形成环,不会,就将to节点加入进来,反之就不加
判断两个节点是否会组成环,通过判断他们是否属于同一 个集合即可

在这里插入图片描述

public class Code04_Kruskal {
    public static class MySets{
        HashMap<Node, List<Node>> setMap = new HashMap<>();

        public MySets(Collection<Node> nodes) {
            for (Node node : nodes) {
                List<Node> list = new ArrayList<>();
                list.add(node);
                setMap.put(node,list);
            }
        }

        private boolean isSameSet(Node from, Node to){
            return setMap.get(from) == setMap.get(to);
        }

        private void union(Node from, Node to){
            List<Node> fromSet = setMap.get(from);
            List<Node> toSet = setMap.get(to);
            for (Node node : toSet) {
                fromSet.add(node);
                setMap.put(node,fromSet);
            }
        }
    }

    public static class EdgeComparator implements Comparator<Edge> {

        @Override
        public int compare(Edge o1, Edge o2) {
            return o1.weight - o2.weight;
        }
    }

    public static Set<Edge> kruskalMST(Graph graph){
        Collection<Node> values = graph.nodes.values();
        MySets mySets = new MySets(values);
        PriorityQueue<Edge> priorityQueue = new PriorityQueue<>(new EdgeComparator());
        for (Edge edge : graph.edges) {
            priorityQueue.add(edge);
        }
        Set<Edge> result = new HashSet<>();
        while (!priorityQueue.isEmpty()){
//            System.out.println(priorityQueue.poll().weight);
            Edge edge = priorityQueue.poll();
            if (!mySets.isSameSet(edge.from,edge.to)){
                result.add(edge);
                mySets.union(edge.from, edge.to);
            }

        }
        return result;
    }

    public static void main(String[] args) {
        Node node1 = new Node(1);
        Node node2 = new Node(2);
        Node node3 = new Node(3);
        Node node4 = new Node(4);
        Edge edge1 = new Edge(2, node1, node2);
        Edge edge2 = new Edge(1, node1, node3);
        Edge edge3 = new Edge(4, node1, node4);
        Edge edge4 = new Edge(3, node2, node4);
        Edge edge5 = new Edge(1, node3, node4);

        ArrayList<Node> list1 = new ArrayList<>();
        list1.add(node2);
        list1.add(node3);
        list1.add(node4);
        node1.nexts = list1;


        ArrayList<Node> list2 = new ArrayList<>();
        list2.add(node4);
        node2.nexts = list2;

        ArrayList<Node> list3 = new ArrayList<>();
        list3.add(node4);
        node3.nexts = list3;

        ArrayList<Node> list4 = new ArrayList<>();
        list4.add(node1);
        list4.add(node2);
        list4.add(node3);

        HashMap<Integer, Node> map = new HashMap<>();
        map.put(1, node1);
        map.put(2, node2);
        map.put(3, node3);
        map.put(4, node4);

        HashSet<Edge> edges = new HashSet<>();
        edges.add(edge1);
        edges.add(edge2);
        edges.add(edge3);
        edges.add(edge4);
        edges.add(edge5);
        Graph graph = new Graph();
        graph.edges = edges;
        graph.nodes = map;

        Set<Edge> set = kruskalMST(graph);
        System.out.println();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值