最小生成树(Java实现)

news2024/11/15 19:26:58

一、Prim算法

        Prim算法基本思想为:从联通网络 N={V,E}中某一顶点 v0 出发,此后就从一个顶点在 S 集中, 另一个顶点不在 S 集中的所有顶点中选择出权值最小的边,把对应顶点加入到 S 集 中, 直到所有的顶点都加入到 S 集中为止。

原始图:

最小生成树:

package algorithm;

public class prim {
    public static void main(String[] args) {
        char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
        int num = vertex.length;
        int[][] edge = {//10000表示两个顶点不通
                {10000, 5, 7, 10000, 10000, 10000, 2},
                {5, 10000, 10000, 9, 10000, 10000, 3},
                {7, 10000, 10000, 10000, 8, 10000, 10000},
                {10000, 9, 10000, 10000, 10000, 4, 10000},
                {10000, 10000, 8, 10000, 10000, 5, 4},
                {10000, 10000, 10000, 4, 5, 10000, 6},
                {2, 3, 10000, 10000, 4, 6, 10000}};

        MGraph mGraph = new MGraph(num);
        MinTree minTree = new MinTree();
        minTree.creatGraph(mGraph, num, vertex, edge);
        minTree.showGraph(mGraph);
        minTree.prim(mGraph, 0);
    }
}


class MGraph {
    int num; //顶点的个数
    char[] vertex; //顶点的元素
    int[][] edge; //存放边

    public MGraph(int num) { //构造器
        this.num = num;
        vertex = new char[num];
        edge = new int[num][num];
    }
}

class MinTree {
    //创建图
    public void creatGraph(MGraph mGraph, int num, char[] vertex, int[][] edge) {
        for (int i = 0; i < num; i++) {
            mGraph.vertex[i] = vertex[i]; //添加每个顶点的名字
            for (int j = 0; j < num; j++) {
                mGraph.edge[i][j] = edge[i][j]; //添加各个城市之间直接相连的边的权值
            }
        }
    }

    //普利姆算法
    public void prim(MGraph mGraph, int node) {
        int[] vis = new int[mGraph.num]; //用于标记遍历过的节点
        vis[node] = 1; //将当前节点标记为1表示已访问
        //用来记录最小路径中两个节点的下标
        int index1 = -1;
        int index2 = -1;
        for (int k = 1; k < mGraph.num; k++) { //若有n个节点 则有n - 1 条边
            int minSide = Integer.MAX_VALUE; //遍历与之比较 找到最小的路径
            for (int i = 0; i < mGraph.num; i++) {
                for (int j = 0; j < mGraph.num; j++) {
                    if (vis[i] == 1 && vis[j] == 0 && mGraph.edge[i][j] < minSide) {
                        minSide = mGraph.edge[i][j]; //最短边上的权值
                        //最短边的两个顶点
                        index1 = i;
                        index2 = j;
                    }
                }
            }
            //从第内层for循环出来后,表示找到一条最短边
            System.out.println("边<" + mGraph.vertex[index1] + "," + mGraph.vertex[index2] + ">权值:" + minSide);
            vis[index2] = 1; //将最内层与已访问节点路径最短的节点设置为已访问
        }
    }

    //输出初始图
    public void showGraph(MGraph mGraph) {
        for (int[] arr : mGraph.edge) {
            for (int element : arr) {
                System.out.print(element + " ");
            }
            System.out.println();
        }
    }
}

二、Kruskal算法

        kruskal其基本思想为:设有一个有 N 个顶点的联通网络 N={V,E},初始时建立一个只有 N 个顶点且没有边的非连通图 T,T 中每个顶点都看作是一个联通分支,从边集 E 中选择出权值最小的边且该边的两个端点不在一个联通分支中,则把该边加入到 T 中,否则就再从E新选择一条权值最小的边,直到所有的顶点都在一个联通分支中为止。

package algorithm;

import java.util.*;
/*
1. 定义一个并查集类,用于判断两个顶点是否属于同一个连通分量
2. 对图中的所有边按照权重进行排序
3. 遍历排序后的边,如果边的两个顶点不属于同一个连通分量,则将这条边加入最小生成树中,并将这两个顶点所在的连通分量合并
4. 重复步骤3,直到最小生成树中的边数等于顶点数减1
*/

class UnionFind {
    int[] parent;//存储每个结点的前驱结点
    int[] rank;//树的高度

    public UnionFind(int n) {
        parent = new int[n];
        rank = new int[n];
        for (int i = 0; i < n; i++) {
            parent[i] = i;//每个结点的上级都是自己
            rank[i] = 1;//每个结点构成的树的高度为1
        }
    }

    public int find(int x) {
        if (parent[x] == x) {//递归出口:x的上级为 x本身,即 x为根结点
            return x;
        }
        return parent[x] = find(parent[x]);//此代码相当于先找到根结点 rootx,然后 parent[x]=rootx
    }

    public boolean union(int x, int y) {
        int rootX = find(x);
        int rootY = find(y);
        if (rootX == rootY) {
            return false;
        }
        if (rank[rootX] > rank[rootY]) {
            parent[rootY] = rootX;
        } else if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY;
        } else {
            parent[rootY] = rootX;
            rank[rootX]++;
        }
        return true;
    }
}

class Edge implements Comparable<Edge> {
    int from;
    int to;
    int weight;

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

    @Override
    public int compareTo(Edge other) {
        return this.weight - other.weight;
    }
}

public class KruskalAlgorithm {
    public static void main(String[] args) {
        int[][] graph = {
                {0, 1, 5},
                {0, 2, 7},
                {0, 6, 2},
                {1, 6, 3},
                {1, 3, 9},
                {2, 4, 8},
                {3, 5, 4},
                {4, 5, 5},
                {4, 6, 4},
                {5, 6, 6},
        };
        List<Edge> edges = new ArrayList<>();
        for (int[] edge : graph) {
            edges.add(new Edge(edge[0], edge[1], edge[2]));
        }
        Collections.sort(edges);
        UnionFind uf = new UnionFind(graph.length);
        List<Edge> result = new ArrayList<>();
        for (Edge edge : edges) {
            if (uf.union(edge.from, edge.to)) {
                result.add(edge);
            }
        }
        System.out.println("最小生成树的边为:");
        for (Edge edge : result) {
            System.out.println(edge.from + " - " + edge.to + " : " + edge.weight);
        }
    }
}

原始图:

最小生成树:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1403329.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RK3568平台 TinyAlsa集成第三方音频算法

一.tinyalsa介绍 ALSA&#xff08;Advanced Linux Sound Architecture&#xff09;是一个开源项目&#xff0c;涵盖了用户空间和内核空间对音频设备的操作接口&#xff0c;通过应用层使用alsalib可以实现对音频设备的控制 TinyAlsa是android推出的一个精简的ALSA库&#xff0c…

【Web实操08】实现一个导航效果,要求横向摆放,并且清除浮动

要实现图片的效果&#xff1a; 要利用浮动的知识点完成首页&#xff0c;电视&#xff0c;平板&#xff0c;家电&#xff0c;服务在一行导航栏剧中居中显示的功能&#xff0c;背景设置为灰黑色&#xff0c;导航栏下面是内容。 代码如下&#xff1a; <!DOCTYPE html> &l…

flink学习之窗口处理函数

窗口处理函数 什么是窗口处理函数 Flink 本身提供了多层 API&#xff0c;DataStream API 只是中间的一环&#xff0c;在更底层&#xff0c;我们可以不定义任何具体的算子&#xff08;比如 map()&#xff0c;filter()&#xff0c;或者 window()&#xff09;&#xff0c;而只是…

springboot集成COS对象存储

1.申请腾讯云存储桶 新建密钥&#xff08;后面配置要用到&#xff09; 2.编写工具类 此处使用工具类进行基本属性配置&#xff0c;也可选择在yml中配置 package com.sfy.util;import com.qcloud.cos.COSClient; import com.qcloud.cos.ClientConfig; import com.qcloud.cos.a…

开源堡垒机JumpServer本地安装并配置公网访问地址

文章目录 前言1. 安装Jump server2. 本地访问jump server3. 安装 cpolar内网穿透软件4. 配置Jump server公网访问地址5. 公网远程访问Jump server6. 固定Jump server公网地址 前言 JumpServer 是广受欢迎的开源堡垒机&#xff0c;是符合 4A 规范的专业运维安全审计系统。JumpS…

计算机服务器中了mallox勒索病毒怎么办,mallox勒索病毒解密数据恢复

企业的计算机服务器存储着企业重要的信息数据&#xff0c;为企业的生产运营提供了极大便利&#xff0c;但网络安全威胁随着技术的不断发展也在不断增加&#xff0c;近期&#xff0c;云天数据恢复中心接到许多企业的求助&#xff0c;企业的计算机服务器中了mallox勒索病毒&#…

IDEA2023.2 将普通项目转Maven项目

1、选中一个普通工程&#xff1a; 2、快捷键&#xff1a;ctrlshift a&#xff0c;搜索&#xff1a;Add Framework Support… 3、勾选maven&#xff0c;点击ok。

谁适合选择虚拟化

情况 前些天,有人问弄虚拟化怎么样: 还有一个群里,讨论了这事: 也弄了很多年了,虽然不算深入,毕竟,也是拼尽了全力,毕竟差不多7年的时光已经投入进去了,回头时,感觉没留下什么,有些十年技术一场空的感觉,真是应了虚拟化这几个字。 现在就大体说说这事: 先看看当前…

网络通信(Socket/TCP/UDP)

一、Socket 1.概念: Socket(又叫套接字)是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元。它是网络通信过程中端点的抽象表示,包含进行网络通信必须的五种信息:连接协议,客户端的IP地址,客户端的端口,服务器的IP地址,服务器的端口。 一个Socket是一对IP地址…

DP专题17 单词拆分

本题链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 题目&#xff1a; 思路&#xff1a; 由题意&#xff0c;根据题目意思&#xff0c;给出字符串 S&#xff0c;以及一个字符串数组&#xff0c;问字符串数组中 是否可以任取字符…

java中stream流进行遍历

在源代码转向加工到目标代码时&#xff0c;可以使用加工流代码加工 三种方式&#xff1a; 1.使用stream流的of方法 Stream.of(arr); 2.使用数组的Arrays.stream Arrays.stream(arr); 3.集合类&#xff0c;继承了Collection的.stream List<Strin…

2.2.1.1-一个关于定投的故(姿)事(势)

跳转到根目录&#xff1a;知行合一&#xff1a;投资篇 已完成&#xff1a; 1、投资&技术   1.1.1 投资-编程基础-numpy   1.1.2 投资-编程基础-pandas   1.2 金融数据处理   1.3 金融数据可视化 2、投资方法论   2.1.1 预期年化收益率   2.1.2 一个关于yaxb的…

工业相机+镜头选型及靶面、焦距计算等相关详解

工业相机镜头选型及靶面、焦距计算等相关详解 着重讲述相机的各个参数及使用意义总结相机镜头选型主要参数的推理计算 0. 工业相机相关概念简介 相机与镜头一览 工业相机与镜头实物图如下图所示&#xff1a; 常见的相机有两种供电方式&#xff1a;一种是电源线供电&#xff0…

码农维权——案例分析之违法解除劳动合同(二)

目录 一、背景 二、案例来源 三、被【非法】解除《劳动合同》后可以主张哪些诉求&#xff1f; 四、案例分析&#xff1a;违法解除劳动合同 A、公司的主张&#xff1a; B、公司的主要证据&#xff08;公司单方面提交的&#xff0c;法院不一定认可采纳&#xff09;&…

QT的绘图系统QPainterDevice与文件系统QIODevice

QT的绘图系统&#xff08;QPainterDevice&#xff09;与文件系统&#xff08;QIODevice&#xff09; 文章目录 1、Qt 的绘图系统1、QPainter的使用2、QPen(画笔&#xff09;及QBursh&#xff08;画刷&#xff09;3、手动更新窗口4、绘图设备1、四种绘图设备的 区别2、 QBitmap3…

革新区块链:代理合约与智能合约升级的未来

作者 张群&#xff08;赛联区块链教育首席讲师&#xff0c;工信部赛迪特聘资深专家&#xff0c;CSDN认证业界专家&#xff0c;微软认证专家&#xff0c;多家企业区块链产品顾问&#xff09;关注张群&#xff0c;为您提供一站式区块链技术和方案咨询。 代理合约&#xff08;Prox…

使用Go语言编写HTTP代理服务器

在Go语言中&#xff0c;编写一个HTTP代理服务器相对简单且直观。代理服务器的主要职责是接收客户端的请求&#xff0c;然后将请求转发到目标服务器&#xff0c;再将目标服务器的响应返回给客户端。下面是一个简单的示例&#xff0c;展示如何使用Go语言编写一个基本的HTTP代理服…

地方债务余额数据,Shp、excel格式,2008-2020年,含公共财政收入、支出、负债率等多个字段

基本信息&#xff1a; 数据名称: 地方债务余额数据 数据格式: Shp、excel 数据时间: 2008-2020年 数据几何类型: 面 数据坐标系: WGS84 数据来源&#xff1a;网络公开数据 数据字段&#xff1a; 序号字段名称字段说明1zfzqsl地方政府债-债券数量(只)2zfzqye地方政府…

美团收银餐饮版培训教程

硬件连接方式及介绍: 双屏收银机 收银一体机 双屏收银机连接图 收银一体机连接图 前台打印机 后厨打印机 标签打印机 前台打印机连接图 后厨打印机连接图 其它收银机配件 软件前期设置 1、机器联网 点开桌面的设置&#xff0c;点击更多&#xff0c;点击以太网&#xff0c;最上…

杭电网课笔记

技巧 1.判断得数为整数还是小数&#xff0c;可以%1&#xff0c;得数为0是整数 或者用instanceof Integer number 9; // 自动装箱 System.out.println(number instanceof Integer); // 输出&#xff1a;true 2.a * b 最大公约数 * 最小公倍数 LCM 最小公倍数 GCD 最大公…