最小生成树(java实现)


/**
 * 定义基本数据结构
 * @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 
{
	int begin;                         
	int end;
	int weight;
	//用于给List排序,实现接口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 eArray = new ArrayList();
	
	//--------------------------------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:eArray
						EStruct 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);
	}
}


你可能感兴趣的:(数据结构)