Kruskal算法

思路

  • 他是先选出各边,然后进行排序,从小到大,下面的代码是存储时就进行升序;
  • 使用并查集来进行判断他是否重边,下面代码使用了路径压缩,应该还是比较好懂的;
  • 然后就没了,思路就是这么简单;
点击查看代码

import java.io.IOException;
import java.util.Scanner;

public class Main {
    static int[] flag;
    public static void main(String[] args) throws IOException {
        LinkNode p;
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        int n = str.length();
        LinkList list = new LinkList();
        for(int i=0;i<n;i++){
            for (int j = 0; j < n; j++) {
                int temp = sc.nextInt();
                if (i >= j) {
                    if (temp != 0) {
                        p = new LinkNode(i, j, temp);
                        list.Insert_order(p);
                    }
                }
            }
        }
        list.Print();
        kruskal(list,n,str);
    }

    //kruskal算法的实现
    private static void kruskal(LinkList L,int n,String str) {
        System.out.println("开始采用kruskal算法选择边:");
        //继续在此完成代码
        int sum=0;
        LinkNode p=L.head;
        flag=new int[n];
        char[] a=str.toCharArray();
        for(int i=0;i<n;i++) {
            flag[i] = i;
        }
        while(p!=null) {
            if(find(p.start)!=find(p.end)) {
                System.out.println(a[p.start]+"-->"+a[p.end]+" = "+p.length);
                sum+=p.length;
                union(p.start,p.end);
            }
            p = p.next;
        }
        System.out.println("总权值为:"+sum);
    }

    private static void union(int x, int y) {
        x=find(flag[x]);
        y=find(flag[y]);
        if (x!=y){
            flag[x]=y;
        }
    }



    private static int find(int target) {
        if (flag[target]==target){
            return target;
        }
        return find(flag[target]);
    }


    public static class LinkNode {
        public int start;   //起点
        public int end;  //终点
        public double length;  //长度
        public LinkNode next;   //下一个结点的引用

        //构造方法
        public LinkNode(){
            this.start = 0;
            this.end = 0;
            this.length = 0;
            this.next = null;
        }
        public LinkNode(int start,int end,double length){
            this.start = start;
            this.end = end;
            this.length = length;
        }
    }

    public static class LinkList {
        public LinkNode head;  //表头结点

        //在链表插入是排序
        public void Insert_order(LinkNode p){
            if(head==null) {
                head=p;
            }else {
                if(p.length<head.length) {
                    p.next=head;
                    head=p;
                }
                else {
                    LinkNode  current= head;
                    while(current.next!=null &&p.length > current.next.length) {
                        current = current.next;
                    }
                    p.next = current.next;
                    current.next = p;
                }
            }

        }
        //输出有序链表
        public void Print(){
            LinkNode p=head.next;
            System.out.println("有序链表输出如下:");
            while(p!=null){
                System.out.println(p.start+"-->"+p.end+" = "+p.length);
                p = p.next;
            }
        }
    }
}

posted @ 2022-04-29 20:48  雨同我  阅读(58)  评论(2编辑  收藏  举报