最小生成树(java实现)

来源:互联网 发布:网络协议的作用是什么 编辑:程序博客网 时间:2024/05/21 10:52


/** * 定义基本数据结构 * @author 小宇 */public class MGraph{  //当边edges[i][j]不存在时,用null表示其值public static final int NULL = 1000;static final int MAXV = 100;                  //边集int[][] edges = new int[this.MAXV][this.MAXV];    //顶点数,和边数int n,e;           }


/** * 该结构用于克鲁斯卡尔算法 * @author 小宇 */public class EStruct implements Comparable<EStruct> {int begin;                         int end;int weight;//用于给List<EStruct>排序,实现接口comparable方法public int compareTo(EStruct e){return this.weight - e.weight;}}


/** * 生成邻接矩阵并输出 * @author 小宇 * */public class CreateGraph {public void createMat(MGraph g, int A[][], int n){              int i, j;g.n = n;g.e = 0;for(i = 0; i < n; i++)for(j = 0; j < n; j++){   g.edges[i][j] = A[i][j];if(g.edges[i][j] != 1000)g.e++;}}//---------------------------------------------------public void DispMat(MGraph g){int i, j;for(i = 0; i < g.n; i++){for(j = 0; j < g.n; j++)if(g.edges[i][j] == g.NULL)System.out.print("-" + " ");else  System.out.print(g.edges[i][j] + " ");System.out.println();}}}



import java.util.ArrayList;import java.util.Collections;import java.util.List;/** * 核心算法 * 用prim算法及克鲁斯卡尔算法求解最小生成树 * @author 小宇 * */public class MinimalSpanningTree {static final int INF = 32767;private  List<EStruct> eArray = new ArrayList<EStruct>();//--------------------------------Prim算法--------------------------------public void Prim(MGraph g, int v){int[] lowcost = new int[g.n];int min;int[] closest = new int[g.n];int i,j,k = 0;for(i = 0; i < g.n; i++){lowcost[i] = g.edges[v][i];closest[i] = v;}for(i = 1; i < g.n; i++){min = INF;for(j = 0; j < g.n; j++)if(lowcost[j] != 0 && lowcost[j] < min){min = lowcost[j];k = j;}System.out.println(  "边" + closest[k] + "," + k + "权值" + min);lowcost[closest[k]] = 0;lowcost[k] = 0;for(j = 0; j < g.n; j++)if(g.edges[k][j] != 0 && g.edges[k][j] < lowcost[j]){lowcost[j] = g.edges[k][j];closest[j] = k;}}}//---------------------克鲁斯卡尔算法-----------------------------------------------public void getEStruct(MGraph mgraph){/** * 用EStruct结构保存每条边 * 最后存于EStruct数组 * 然后用java类库提供方法排序 */for(int i = 0;i < mgraph.n; i++){for(int j = 0; j < mgraph.n; j++){//由于是无向图if(j < i){//如果begin:i , end: j ,的边存在if(mgraph.edges[i][j] != mgraph.NULL){//创建EStruct保存该边信息并加入List:eArrayEStruct estruct = new EStruct();estruct.begin = i;estruct.end = j;estruct.weight = mgraph.edges[i][j];eArray.add(estruct);}}}}//用java类库提供方法排序Collections.sort(eArray);}//查找连线顶点的尾部下标public int find(int[] p,int f){while(p[f] != 0)f = p[f];return f;}public void Kruskal(MGraph mgraph){int i, n, m;//parent数组用于判断数组边集是否形成环路int[] parent = new int[eArray.size()];//初始化数组为零for(i = 0; i < eArray.size(); i++)parent[i] = 0;//循环生成最小生成树,最小生成树的边数为图的(顶点数 - 1)for(i = 0; i  < mgraph.n - 1; i++){n = find(parent, eArray.get(i).begin);m = find(parent,eArray.get(i).end);//如果n不等于m说明此边与现有生成树没有形成环路if(n != m){//将此边的表尾节点放入下标为起点的parent中//表明此顶点已在生成树集合中parent[n] = m;System.out.println(eArray.get(i).begin + "," +  eArray.get(i).end + "  权:" + eArray.get(i).weight);}}}}


/** * 测试代码 * 生成邻接矩阵->prim->kruskal * @author 小宇 * */public class Test {public static void main(String[] args){MGraph mgraph = new MGraph();int[][] array = new int[6][6];for(int i = 0;i < 6; i++)for(int j = 0;j < 6; j++)array[i][j] = mgraph.NULL;array[0][1] = 6;array[1][0] = 6;array[0][3] = 5;array[3][0] = 5;array[0][2] = 1;array[2][0] = 1;array[1][2] = 5;array[2][1] = 5;array[2][3] = 5;array[3][2] = 5;array[1][4] = 3;array[4][1] = 3;array[4][2] = 6;array[2][4] = 6;array[2][5] = 4;array[5][2] = 4;array[4][5] = 6;array[5][4] = 6;array[3][5] = 2;array[5][3] = 2;CreateGraph myGraph = new CreateGraph();System.out.println("创建邻接矩阵:");myGraph.createMat(mgraph,array, 6);myGraph.DispMat(mgraph);System.out.println("Prim算法生成最小生成树:");MinimalSpanningTree mst = new MinimalSpanningTree();mst.Prim(mgraph, 0);mst.getEStruct(mgraph);mst.Kruskal(mgraph);}}


0 0
原创粉丝点击