Kruskal算法求最小生成树(java)

合集下载

数据结构(Java版)图2(最小生成树)

数据结构(Java版)图2(最小生成树)

最小生成树举例
A
50 60 52 65 50
C
45 42 30 50
A
C
45
B
40
D
G
B
40 50
D
42 30
G
E
70
F
E
F
(a) 无向带权连通图G
(b) 无向带权图G 的最小生成树T
从最小生成树的定义可知,构造n个顶点的无向带权连 通图的最小生成树,必须满足如下三个条件: ① 必须包含n个顶点。 ② 有且仅有n-1条边。 ③ 没有回路。

将ej边加入到tree中;
}
实践项目

设计一个程序实现Prim和Kruskal算法.
表5-1 lowcost[ ]数组数据变化情况 表5-2 closest[ ]数组数据变化情况
扫描次数
closest[0]
closest[1]
closest[2]
closest[3]
closest[4]
closest[5]
求最小生成树算法

普里姆算法(Prim) (从点着手)

适合于求边稠密的最小生成树 适合于求边稀疏的最小生成树

克鲁斯卡尔算法(Kruskal)(从边着手)

普里姆算法(Prim)思想
1.
2.
3.
4.
令集合U={u0}(即从顶点u0开始构造最小生 成树),集合T={}。 从所有顶点u∈U和顶点v∈V-U的边权中选择最 小权值的边(u,v),将顶点v加入到集合U中,边 (u,v)加入到集合T中。 如此重复下去,直到U=V时则最小生成树构造完 毕。 此时集合U就是最小生成树的顶点集合,集合T 就是最小生成树的边集。

Kruskal克鲁斯卡尔最小生成树算法(贪心算法)

Kruskal克鲁斯卡尔最小生成树算法(贪心算法)

Kruskal克鲁斯卡尔最⼩⽣成树算法(贪⼼算法)1. /*2. * Introduction to Algorithms3. * Chapter 23 --- MST.Kruskal4. * Tanky Woo @ 5. * 2012.1.76. */7.8. #include <</span>iostream>9. #include <</span>algorithm>10. using namespace std;11.12. const int maxint = 999999;13.14. typedef struct Road{15. int c1, c2;// a到b16. int value;//权值17. }Road;18.19. int no;20. int line;//记录实际关系数21. Road road[100];//设⼀个⽐较⼤的值,实际看输⼊最⼩⽣成树中:边数e=n-122. int node[101];//最⼩⽣成树:n顶点数23.24. bool myCmp(const Road &a,const Road &b)25. {26. if(a.value <</span> b.value)27. return 1;28. return 0;29. }30.31. //node[2]=1 node[8]=1 ,node[3]=1,共同的祖先,如果(3,8)加进去,则构成回路,不要32. //有点像并查集33. int Find_Set(int n)34. {35. if(node[n]==-1)36. return n;37. return node[n]= Find_Set(node[n]);38. }39.40. bool Merge(int s1,int s2)41. {42. int r1 = Find_Set(s1);43. int r2 = Find_Set(s2);44. if(r1 == r2)//如果相等证明构成回路,则直接返回⼀个0,不要把顶点加进来(下⼀步是加进去的)45. return 0;46. if(r1 <</span> r2)47. node[r2]= r1;48. else49. node[r1]= r2;50. return 1;51. }52.53. int main()54. {55. freopen("input.txt","r", stdin);56. //初始化全为-157. memset(node,-1, sizeof(node));58. scanf("%d",&no);59. scanf("%d",&line);60. int i;61. for(i=0; i<</span>line; ++i)62. {63. cin >> road[i].c1 >> road[i].c2 >> road[i].value;64. }65. sort(road, road+line, myCmp);66. int sum = 0, count = 0;// sum是MST的值,count是记录已使⽤的点数67. for(i=0; i<</span>line; ++i)68. {69. if(Merge(road[i].c1, road[i].c2))//如果返回的为0,则证明构成回路,不要加进70. {71. count ++;72. sum += road[i].value;73. }74. if(count == no-1)//e=n-1已经连通,可以退出75. break;76. }77. cout <</span><</span> sum <</span><</span> endl;78. return 0;79. }80.81.82. /*83. input.txt:84. 985. 1486. 1 2 487. 1 8 888. 2 3 889. 2 8 1190. 3 4 791. 3 6 492. 3 9 293. 4 5 994. 4 6 1495. 5 6 1096. 6 7 297. 7 8 198. 7 9 699. 8 9 7100. */。

最小生成树的Kruskal算法实现

最小生成树的Kruskal算法实现

#include<stdio.h>#include<stdlib.h>#define M 20#define MAX 20typedef struct{int begin;int end;int weight;}edge;typedef struct{int adj;int weight;}AdjMatrix[MAX][MAX];typedef struct{AdjMatrix arc;int vexnum, arcnum;}MGraph;void CreatGraph(MGraph *);//函数申明void sort(edge* ,MGraph *);void MiniSpanTree(MGraph *);int Find(int *, int );void Swapn(edge *, int, int);void CreatGraph(MGraph *G)//构件图{int i, j,n, m;printf("请输入边数和顶点数:\n");scanf("%d %d",&G->arcnum,&G->vexnum);for (i = 1; i <= G->vexnum; i++)//初始化图{for ( j = 1; j <= G->vexnum; j++){G->arc[i][j].adj = G->arc[j][i].adj = 0;}}for ( i = 1; i <= G->arcnum; i++)//输入边和权值{printf("请输入有边的2个顶点\n");scanf("%d %d",&n,&m);while(n < 0 || n > G->vexnum || m < 0 || n > G->vexnum) {printf("输入的数字不符合要求请重新输入:\n");scanf("%d%d",&n,&m);}G->arc[n][m].adj = G->arc[m][n].adj = 1;getchar();printf("请输入%d与%d之间的权值:\n", n, m);scanf("%d",&G->arc[n][m].weight);}printf("邻接矩阵为:\n");for ( i = 1; i <= G->vexnum; i++){for ( j = 1; j <= G->vexnum; j++){printf("%d ",G->arc[i][j].adj);}printf("\n");}}void sort(edge edges[],MGraph *G)//对权值进行排序{int i, j;for ( i = 1; i < G->arcnum; i++){for ( j = i + 1; j <= G->arcnum; j++){if (edges[i].weight > edges[j].weight){Swapn(edges, i, j);}}}printf("权排序之后的为:\n");for (i = 1; i < G->arcnum; i++){printf("<< %d, %d >> %d\n", edges[i].begin, edges[i].end, edges[i].weight); }}void Swapn(edge *edges,int i, int j)//交换权值以及头和尾{int temp;temp = edges[i].begin;edges[i].begin = edges[j].begin;edges[j].begin = temp;temp = edges[i].end;edges[i].end = edges[j].end;edges[j].end = temp;temp = edges[i].weight;edges[i].weight = edges[j].weight;edges[j].weight = temp;}void MiniSpanTree(MGraph *G)//生成最小生成树{int i, j, n, m;int k = 1;int parent[M];edge edges[M];for ( i = 1; i < G->vexnum; i++){for (j = i + 1; j <= G->vexnum; j++){if (G->arc[i][j].adj == 1){edges[k].begin = i;edges[k].end = j;edges[k].weight = G->arc[i][j].weight;k++;}}}sort(edges, G);for (i = 1; i <= G->arcnum; i++){parent[i] = 0;}printf("最小生成树为:\n");for (i = 1; i <= G->arcnum; i++)//核心部分{n = Find(parent, edges[i].begin);m = Find(parent, edges[i].end);if (n != m)//判断是否有回路,如果有,舍弃{parent[m] = n;printf("<< %d, %d >> %d\n", edges[i].begin, edges[i].end, edges[i].weight); }}}int Find(int *parent, int f)//找尾{while ( parent[f] > 0){f = parent[f];}return f;}int main(void)//主函数{MGraph *G;G = (MGraph*)malloc(sizeof(MGraph));if (G == NULL){printf("memory allcation failed,goodbye");exit(1);}CreatGraph(G);MiniSpanTree(G);system("pause");return 0;}/%BD%F5%B1%F3ljb/blog/item/7bce9a339f74f049ac4b5f30.html#include "heap.h"#include "UFSets.h"template <class T, class E>void Kruskal (Graph<T, E>& G,MinSpanTree<T, E>& MST) {MSTEdgeNode<T, E> ed; //边结点辅助单元int u, v, count;int n = G.NumberOfVertices(); //顶点数int m = G.NumberOfEdges(); //边数MinHeap <MSTEdgeNode<T, E>> H(m); //最小堆UFSets F(n); //并查集for (u = 0; u < n; u++)for (v = u+1; v < n; v++)if (G.getWeight(u,v) != maxValue) {ed.tail = u; ed.head = v; //插入堆ed.cost = G.getWeight (u, v);H.Insert(ed);count = 1; //最小生成树边数计数while (count < n) { //反复执行, 取n-1条边H.Remove(ed); //退出具最小权值的边u = F.Find(ed.tail); v = F.Find(ed.head);//取两顶点所在集合的根u与vif (u != v) { //不是同一集合,不连通F.Union(u, v); //合并,连通它们MST.Insert(ed); //该边存入MSTcount++;}}};。

数据结构-kruskal算法求最小生成树_实验报告

数据结构-kruskal算法求最小生成树_实验报告

一、问题简述题目:图的操作。

要求:用kruskal算法求最小生成树。

最短路径:①输入任意源点,求到其余顶点的最短路径。

②输入任意对顶点,求这两点之间的最短路径和所有路径。

二、程序设计思想首先要确定图的存储形式。

经过的题目要求的初步分析,发现该题的主要操作是路径的输出,因此采用边集数组(每个元素是一个结构体,包括起点、终点和权值)和邻接矩阵比较方便以后的编程。

其次是kruskal算法。

该算法的主要步骤是:GENERNIC-MIT(G,W)1. A←2. while A没有形成一棵生成树3 do 找出A的一条安全边(u,v);4.A←A∪{(u,v)};5.return A算法设置了集合A,该集合一直是某最小生成树的子集。

在每步决定是否把边(u,v)添加到集合A中,其添加条件是A∪{(u,v)}仍然是最小生成树的子集。

我们称这样的边为A 的安全边,因为可以安全地把它添加到A中而不会破坏上述条件。

然后就是Dijkstra算法。

Dijkstra算法基本思路是:假设每个点都有一对标号 (d j, p j),其中d j是从起源点s到点j的最短路径的长度 (从顶点到其本身的最短路径是零路(没有弧的路),其长度等于零);p j则是从s到j的最短路径中j点的前一点。

求解从起源点s到点j的最短路径算法的基本过程如下:1) 初始化。

起源点设置为:① d s=0, p s为空;②所有其他点: d i=∞, p i=?;③标记起源点s,记k=s,其他所有点设为未标记的。

2) 检验从所有已标记的点k到其直接连接的未标记的点j的距离,并设置:d j=min[d j, d k+l kj]式中,l kj是从点k到j的直接连接距离。

3) 选取下一个点。

从所有未标记的结点中,选取d j中最小的一个i:d i=min[d j, 所有未标记的点j]点i就被选为最短路径中的一点,并设为已标记的。

4) 找到点i的前一点。

从已标记的点中找到直接连接到点i的点j*,作为前一点,设置:i=j*5) 标记点i。

Kruskal算法计算最小生成树(java)

Kruskal算法计算最小生成树(java)

J avaMan_chen的专栏K ruskal算法计算最小生成树(java)分类: 算法 2012-12-04 17:15 243人阅读 评论(2) 收藏举报kruskalKruskal克鲁斯卡尔最小生成树最小生成树定义:每一个无向图可拆分成多个子图,在这些子图中,如果图的各个顶点没有形成回路,则是图的一颗生成树。

最小生成树的意识是树的相邻节点距离之和最小。

应用场景:张三被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。

张三已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。

为了用最小的消费,他想铺设最短的光纤去连接所有的农场,问要如何实现。

算法实现:有关最小生成树的问题常见的算法有两种,分别是Kruskal(克鲁斯卡尔)算法和Prim(普里姆)算法,本文讲解Kruskal算法的实现Kruskal算法的计算流程大致如下:1.将无向图的边按距离长短递增式排序,放到集合中2.遍历该集合,找出最短的边,加入到结果生成树的集合中3.如果结果生成树出现回路,则放弃这条边4.重新执行步骤2,直至所有顶点被遍历可以看出在每次遍历过程中采用了贪心算法算法实例图:代码实现:Edge类用与封装无向图中每条边的信息public class Edge implements Comparable<Edge>{private String start;private String end;private int distance;public Edge(String start,String end,int distance){this.start=start;this.end=end;this.distance=distance;}public String getStart() {return start;}public void setStart(String start) {this.start = start;}public String getEnd() {return end;}public void setEnd(String end) {this.end = end;}public int getDistance() {return distance;}public void setDistance(int distance) {this.distance = distance;}@Overridepublic String toString() {return start + "->" + end;}@Overridepublic int compareTo(Edge obj) {int targetDis=obj.getDistance();return distance>targetDis?1:(distance==targetDis?0:-1);}}MapBuilder类用于构建数据源(数据源结构如上图所示):public class MapBuilder {public TreeSet<Edge> build(){TreeSet<Edge> edges=new TreeSet<Edge>();edges.add(new Edge("A","B",1));edges.add(new Edge("A","C",4));edges.add(new Edge("A","F",6));edges.add(new Edge("B","D",8));edges.add(new Edge("B","E",3));edges.add(new Edge("C","F",5));edges.add(new Edge("C","E",9));edges.add(new Edge("D","E",7));edges.add(new Edge("D","F",10));edges.add(new Edge("E","F",2));return edges;}public int getPointNum(){return 6;}}Kruskal类用于计算最小生成树public class Kruskal {private Set<String> points=new HashSet<String>();private List<Edge> treeEdges=new ArrayList<Edge>();public void buildTree(){MapBuilder builder=new MapBuilder();TreeSet<Edge> edges=builder.build();int pointNum=builder.getPointNum();for(Edge edge:edges){if(isCircle(edge)){continue;}else{//没有出现回路,将这条边加入treeEdges集合treeEdges.add(edge);//如果边数等于定点数-1,则遍历结束if(treeEdges.size()==pointNum-1){return;}}}}public void printTreeInfo(){int totalDistance=0;for(Edge edge:treeEdges){totalDistance+=edge.getDistance();System.out.println(edge.toString());}System.out.println("总路径长度:"+totalDistance);}private boolean isCircle(Edge edge){int size=points.size();if(!points.contains(edge.getStart())){size++;}if(!points.contains(edge.getEnd())){size++;}if(size==treeEdges.size()+1){return true;}else{points.add(edge.getStart());points.add(edge.getEnd());return false;}}}Main类用于测试Kruskal算法public class Main {public static void main(String[] args) {Kruskal test=new Kruskal();test.buildTree();test.printTreeInfo();}}打印输出:A->BE->FB->EA->CD->E总路径长度:17。

Kruskal算法求最小生成树(java)

Kruskal算法求最小生成树(java)

Kruskal算法求最小生成树(JA V A)代码:package homework;import java.util.Scanner;import java.util.Arrays;import java.util.ArrayList;class Edge {public int start;//始边public int end;//终边public double cost;//权重}public class MinSpanningTree_Kruskal{private static int MAX = 100;private ArrayList<Edge> edge = new ArrayList<Edge>();//整个图的边private ArrayList<Edge> target = new ArrayList<Edge>();//目标边,最小生成树private int[] parent = new int[MAX];//标志所在的集合private static double INFINITY = 99999999.99;//定义无穷大private double mincost = 0.0;//最小成本private int n;//结点个数public MinSpanningTree_Kruskal(){}public static void main(String args[]){MinSpanningTree_Kruskal sp = new MinSpanningTree_Kruskal();sp.init();sp.kruskal();sp.print();}//初始化public void init(){Scanner scan = new Scanner(System.in);int p,q;double w;System.out.println("请输入结点个数:");n = scan.nextInt();System.out.println("请输入各条边及权值(每次输入一组数据按回车确认," +"最后输入-1 -1 -1 结束输入过程)");while(true){p = scan.nextInt();q = scan.nextInt();w = scan.nextDouble();if(p < 0 || q < 0 || w < 0){break;}Edge e = new Edge();e.start = p; e.end = q; e.cost = w;edge.add(e);}mincost = 0.0;for(int i = 1; i <= n; ++i){parent[i] = i;}}//集合合并public void union(int j, int k){for(int i = 1; i <= n; ++i){if(parent[i] == j){parent[i] = k;}}}//prim算法主体public void kruskal(){//找剩下的n-2条边int i = 0;while(i < n-1 && edge.size() > 0){//每次取一最小边,并删除double min = INFINITY;int tag = 0;Edge tmp = null;for(int j = 0; j < edge.size(); ++j){Edge tt = edge.get(j);if(tt.cost < min){min = tt.cost;tmp = tt;}}int jj = parent[tmp.start];int kk = parent[tmp.end];//去掉环if(jj != kk){++i;target.add(tmp);mincost += tmp.cost;union(jj,kk);}edge.remove(tmp);}if(i != n-1){System.out.println("没有最小生成树");System.exit(0);}}//打印结果public void print(){double sum=0;System.out.println("最小生成树:");for(int i = 0; i < target.size(); ++i){Edge e = target.get(i);System.out.println("第" + (i+1) + "条边: " + e.start + "---" + e.end+ " 权值:" + e.cost);sum=sum+e.cost;}System.out.println("最小生成树的权值:" + sum);}}调试结果:。

Kruskal算法求最小生成树

Kruskal算法求最小生成树

荆楚理工学院课程设计成果学院:_______计算机工程学院__________ 班级: 14计算机科学与技术一班学生姓名: 陈志杰学号: 2014407020137设计地点(单位)_____B5101_________ ____________设计题目:克鲁斯卡尔算法求最小生成树__________________________________完成日期:2015年1月6日指导教师评语: ______________ ____________________________________________________________________________________________________________ ___________________________________________________________________________________________ ___________________________ __________ _成绩(五级记分制):_____ _ __________教师签名:__________ _______________注:介于A和C之间为B级,低于C为D级和E级。

按各项指标打分后,总分在90~100为优,80~89为良,70~79为中,60~69为及格,60分以下为不及格。

目录1 需求分析 (1)1.1系统目标 (1)1.2主体功能 (1)1.3开发环境 (1)2 概要设计 (1)2.1功能模块划分 (1)2.2 系统流程图 (2)3 详细设计 (3)3.1 数据结构 (3)3.2 模块设计 (3)4测试 (3)4.1 测试数据 (3)4.2测试分析 (4)5总结与体会 (6)5.1总结: (6)5.2体会: (6)参考文献 (7)附录全部代码 (8)1 需求分析1.1系统目标Kruskal算法是一种按照网中边的权值递增的顺序构造最小生成树的方法。

贪心策略-最小生成树prim和克利斯卡尔java算法源程序

贪心策略-最小生成树prim和克利斯卡尔java算法源程序

实验报告9课程数据构造与算法实验名称贪心策略第页班级11计本学号姓名风律澈实验日期:2021年4月27日报告退发(订正、重做)一、实验目的掌握贪心策略的原理和应用。

二、实验环境1、微型计算机一台2、WINDOWS操作系统,Java SDK,Eclipse开发环境三、实验内容必做题:1、编写程序,实现最小生成树prim算法。

2、编写程序,实现最小生成树Kruskal算法。

四、实验步骤和结果(附上代码和程序运行结果截图)1,primpublic class main {/***@param args*/public static final int maxvalue=Integer.MAX_VALUE;public static void// TODO Auto-generated method stubint weight[][]={{0,6,1,5,maxvalue,maxvalue},{6,0,5,maxvalue,3,maxvalue},{1,5,0,5,6,4},{5,maxvalue,5,0,maxvalue,2},{maxvalue,3,6,maxvalue,0,6},{maxvalue,maxvalue,4,2,6,0},};graph a=new graph(weight);a.showprimtree();}}importimportpublic class graph {private ArrayList<vex> vexs;//定义顶点,进入顶点定义初始化public graph(int weight[][]){super();this.vexs=new ArrayList<vex>();//生成顶点集对象实例//start和end是在下面程序中使用以构造边的//vex start;vex end;for(int i=0;i<weight.length;i++)//对顶点集的每个元素生成点对象实例this.vexs.add(new vex());for(int i=0;i<weight.length;i++){//对每个元素进展构造初始化start=this.vexs.get(i);for(int j=0;j<weight.length;j++){if(weight[i][j]!=Integer.MAX_VALUE){end=this.vexs.get(j);new side(start,end,weight[i][j]);}}}}//至此图的所有成分的信息已经完成,返回mainpublic ArrayList<side> prim(){ArrayList<side> tree=new ArrayList<side>();PriorityQueue<side> pq=new PriorityQueue<side>();vex v = this.vexs.get(0);v.setcheck(1);side s;pq.addAll(v.getsides());while (true) {if(pq.isEmpty())break;s=pq.poll();if(s.check_intree()==1){s.un_in();continue;}v=s.add_tree();tree.add(s);pq.addAll(v.getsides());}return tree;}public void showprimtree() {System.out.println(prim());}}importpublic class vex {private static int ids=0;private int id;private int check;ArrayList<side> sides;public vex(){super();id=ids++;check=0;sides=new ArrayList<side>();}public int getid(){return id;}public int getcheck(){return check;}public void setcheck(int i){this.check=i;}public ArrayList<side> getsides(){return sides;}public void addside(side s){this.sides.add(s);}}public class side implements Comparable<side>{private vex start;private vex end;private int weight;private int state;//0表示没有动过,1表示处理过,2表示参加树public side(vex s, vex e, int w) {// TODO Auto-generated constructor stubsuper();this.start=s;this.end=e;this.weight=w;this.state=0;s.addside(this);e.addside(this);}public vex add_tree(){if(this.start.getcheck()==0){start.setcheck(1);this.state=2;return start;}end.setcheck(1);return end;}public int check_intree(){if(start.getcheck()+end.getcheck()==2) return 1;return 0;}public int check_idea(){if (this.state>0) return 1;elsereturn 0;}public void un_in(){this.state=1;}@Overridepublic int compareTo(side o) {// TODO Auto-generated method stubif(this.weight>o.weight) return 1;if(this.weight<o.weight) return -1;return 0;}public String toString(){return"边("+this.start.getid()+","+this.end.getid()+")"; }}2.kruscal算法package最小生成树;public class main {/*** @param args*/public static final int maxvalue=Integer.MAX_VALUE;public static void main(String[] args) {// TODO Auto-generated method stubint weight[][]={{0,6,1,5,maxvalue,maxvalue},{6,0,5,maxvalue,3,maxvalue},{1,5,0,5,6,4},{5,maxvalue,5,0,maxvalue,2},{maxvalue,3,6,maxvalue,0,6},{maxvalue,maxvalue,4,2,6,0},};graph a=new graph(weight);a.showkurscaltree();}}package最小生成树;importimportpublic class graph {private ArrayList<vex> vexs;//定义顶点,进入顶点定义初始化private ArrayList<side> sides;public graph(int weight[][]){super();this.vexs=new ArrayList<vex>();//生成顶点集对象实例this.sides=new ArrayList<side>();//start和end是在下面程序中使用以构造边的//vex start;vex end;for(int i=0;i<weight.length;i++)//对顶点集的每个元素生成点对象实例this.vexs.add(new vex());for(int i=0;i<weight.length;i++){//对每个元素进展构造初始化start=this.vexs.get(i);for(int j=0;j<weight.length;j++){if(weight[i][j]!=Integer.MAX_VALUE){end=this.vexs.get(j);this.sides.add(newside(start,end,weight[i][j]));}}}}//至此图的所有成分的信息已经完成,返回mainpublic ArrayList<side> kurscal(){ArrayList<side> tree=new ArrayList<side>();PriorityQueue<side> pq=new PriorityQueue<side>();pq.addAll(this.sides);side s;while (true) {if(pq.isEmpty())break;s=pq.poll();if(s.together()==1){tree.add(s);}}return tree;}public void showkurscaltree() {System.out.println(kurscal());}}package最小生成树;importpublic class vex {private static int ids=1;private int id;ArrayList<vex> vexs;public vex(){super();id=ids++;this.vexs=new ArrayList<vex>();this.vexs.add(this);}public int getid(){return id;}public ArrayList<vex> getvexs(){return vexs;}public void setvexs(ArrayList<vex> vs){this.vexs.remove(this);vs.add(this);this.vexs=vs;}}package最小生成树;importpublic class side implements Comparable<side>{private vex start;private vex end;private int weight;public side(vex s, vex e, int w) {// TODO Auto-generated constructor stubsuper();this.start=s;this.end=e;this.weight=w;}@Overridepublic int compareTo(side o) {// TODO Auto-generated method stubif(this.weight>o.weight) return 1;if(this.weight<o.weight) return -1;return 0;}public String toString(){return"边("+this.start.getid()+","+this.end.getid()+")";}public int together() {// TODO Auto-generated method stubArrayList<vex> vexsstart=start.getvexs();ArrayList<vex> vexsend=end.getvexs();ArrayList<vex> vexst;vex v;if(vexsstart==vexsend)return 0;if(vexsstart.size()<vexsend.size()){vexst=vexsstart;vexsstart=vexsend;vexsend=vexst;}while(true){if(vexsend.isEmpty())break;v=vexsend.get(0);v.setvexs(vexsstart);}return 1;}}五、实验总结(本次实验完成的情况,心得体会)。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Kruskal算法求最小生成树(JA V A)
代码:
package homework;
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
class Edge {
public int start;//始边
public int end;//终边
public double cost;//权重
}
public class MinSpanningTree_Kruskal{
private static int MAX = 100;
private ArrayList<Edge> edge = new ArrayList<Edge>();//整个图的边
private ArrayList<Edge> target = new ArrayList<Edge>();//目标边,最小生成树private int[] parent = new int[MAX];//标志所在的集合
private static double INFINITY = 99999999.99;//定义无穷大
private double mincost = 0.0;//最小成本
private int n;//结点个数
public MinSpanningTree_Kruskal(){}
public static void main(String args[]){
MinSpanningTree_Kruskal sp = new MinSpanningTree_Kruskal();
sp.init();
sp.kruskal();
sp.print();
}//初始化
public void init(){
Scanner scan = new Scanner(System.in);
int p,q;
double w;
System.out.println("请输入结点个数:");
n = scan.nextInt();
System.out.println("请输入各条边及权值(每次输入一组数据按回车确认," +
"最后输入-1 -1 -1 结束输入过程)");
while(true){
p = scan.nextInt();
q = scan.nextInt();
w = scan.nextDouble();
if(p < 0 || q < 0 || w < 0){
break;
}
Edge e = new Edge();
e.start = p; e.end = q; e.cost = w;
edge.add(e);
}
mincost = 0.0;
for(int i = 1; i <= n; ++i){
parent[i] = i;
}
}//集合合并
public void union(int j, int k){
for(int i = 1; i <= n; ++i){
if(parent[i] == j){
parent[i] = k;
}
}
}//prim算法主体
public void kruskal(){
//找剩下的n-2条边
int i = 0;
while(i < n-1 && edge.size() > 0){
//每次取一最小边,并删除
double min = INFINITY;
int tag = 0;
Edge tmp = null;
for(int j = 0; j < edge.size(); ++j){
Edge tt = edge.get(j);
if(tt.cost < min){
min = tt.cost;
tmp = tt;
}
}
int jj = parent[tmp.start];
int kk = parent[tmp.end];
//去掉环
if(jj != kk){
++i;
target.add(tmp);
mincost += tmp.cost;
union(jj,kk);
}
edge.remove(tmp);
}
if(i != n-1){
System.out.println("没有最小生成树");
System.exit(0);
}
}//打印结果
public void print(){
double sum=0;
System.out.println("最小生成树:");
for(int i = 0; i < target.size(); ++i){
Edge e = target.get(i);
System.out.println("第" + (i+1) + "条边: " + e.start + "---" + e.end
+ " 权值:" + e.cost);
sum=sum+e.cost;
}
System.out.println("最小生成树的权值:" + sum);
}
}
调试结果:。

相关文档
最新文档