My_Graph prim

package interview.src;

import java.util.ArrayList;
import java.util.Scanner;

import javax.naming.InitialContext;

public class My_Graph {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
//1. for prim
		float m = Float.MAX_VALUE;
		float[][] weight = {
				// 0 1  2  3  4  5  6
				{ 0, 0, 0, 0, 0, 0, 0 }, // 0
				{ 0, m, 6, 1, 5, m, m }, // 1
				{ 0, 6, m, 5, m, 3, m }, // 2
				{ 0, 1, 5, m, 5, 6, 4 }, // 3
				{ 0, 5, m, 5, m, m, 2 }, // 4
				{ 0, m, 3, 6, m, m, 6 }, // 5
				{ 0, m, m, 4, 2, 6, m } };// 6 上图的矩阵
//		prim(weight.length - 1, weight);
		// 加入点3. 3---1
		// 加入点6. 6---3
		// 加入点4. 4---6
		// 加入点2. 2---3
		// 加入点5. 5---2

//2. for kruskal
//		My_Graph kr=new My_Graph();
//		kr.init();
//		kr.kruskal();
	
	}
	//1. for prim
	public static void prim(int num, float[][] weight) {
		float[] lowcost = new float[num + 1]; // 到新集合的最小权
		int	 [] closest = new int[num + 1]; // 代表与目标s集合相连的最小权边的点
		boolean[] visited = new boolean[num + 1]; // s[i] == true代表i点在s目标集合中

		visited[1] = true; // 将第一个点放入s集合
		System.out.println("起始节点为" + 1);
		for (int i = 2; i <= num; i++) { // 初始化辅助数组
			lowcost[i] = weight[1][i];
			closest[i] = 1;
			visited[i] = false;
			// System.out.println(lowcost[i]+" "+closest[i]+" "+visited[i]);
		}

		for (int i = 1; i < num; i++) {
			float min = Float.MAX_VALUE;
			int j = 1; // 记录选出的顶点
			for (int k = 2; k <= num; k++) {
				if ((lowcost[k] < min) && (!visited[k])) { // 行遍历,选出lowcost中最小的,并记下对应的顶点,构成了一条边
					min = lowcost[k]; // 最小的权值
					j = k; // 选出的顶点k,给j
				}
			}
			System.out.println("加入点" + j + ". 新加入边" + closest[j] + "---" + j);// 新加入的点j
																				// 和
																				// 与j相连的点
			visited[j] = true; // 加入新点j

			for (int k = 2; k <= num; k++) {
				if ((weight[j][k] < lowcost[k]) && (!visited[k])) {
					lowcost[k] = weight[j][k];
					closest[k] = j; // 距离k顶点最近的点j
				}
				System.out.print(closest[k]+" ");
				
			}
			System.out.println("  <——— closest数组");
		}
	}

	//2. for kruskal
	/*
	 * Max:定义顶点数组的最大值 
	 * edge:链表edge,存储构造的Edge对象 
	 * target:链表trget,存储最终得到结果的Edge对象
	 * parent:存储顶点信息的数组 ,避免产生回路
	 * n:顶点数
	 */
	int Max = 100;
	ArrayList<Edge> edge = new ArrayList<Edge>();
	ArrayList<Edge> target = new ArrayList<Edge>();
	int[] parent = new int[Max];
	Float TheMax = Float.MAX_VALUE;
	int n;

	public void init() {
		/**
		 * p:起始顶点 q:结束顶点 w:边的权值 n:顶点个数
		 */
		Scanner scan = new Scanner(System.in);
		int p, q;
		double w;
		System.out.println("请输入结点的个数:");
		n = scan.nextInt();  //节点个数
		
		System.out.println("按照'A,B,C'的格式输入边与边的信息,ABC分别代表边的起始顶点,结束顶点,权值(输入-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();  //构造edge对象,边
			e.start = p;
			e.end = q;
			e.weight = w;
			
			edge.add(e);   //将构造的Edge对象加到edge链表里 
		}
		
		for (int i = 1; i <= n; ++i) { // 初始化边的信息数组1-n
			parent[i] = i;
		}
	}
	 /*
	  * 对象合并,将上一对象的结束边k, 作为下一对象的起始边j,类似于closest数组
	  */
	public void union(int j, int k) {
		for (int i = 1; i <= n; ++i) {   //遍历数组,
			if (parent[i] == j)
				parent[i] = k;  		//将所有的j值换成k值,不是换一个
		}
	}

	public void kruskal() {
		int i = 1; // 顶点, n-1次,n-1条边
		while (i < n && edge.size() > 0) { 	// 在剩下的边中找权值最小的边,最多找n次
			double min = Double.MAX_VALUE;  //权值最小
			Edge temp = null;               //边的临时变量
			for (int j = 0; j < edge.size(); ++j) { // 遍历所有边
				Edge tt = edge.get(j);
				if (tt.weight < min) { 				//找到权值最小的边,给temp
					min = tt.weight;
					temp = tt;
				}
			}

			// 构造一棵树
			int jj = parent[temp.start];	//找到的权值最小的边的 起始顶点	
			int kk = parent[temp.end];		//找到的权值最小的边的 结束顶点

			if (jj != kk) {        // 如果加入该边不会形成闭合回路
				++i;               //寻找下一条边
				target.add(temp);  //将找到的边放入目标集合
				union(jj, kk);     //以end作为下一条边的start
			}
			edge.remove(temp); // 将找到的边从边集合中删除
		}
		
		System.out.println("最小生成树的路径是:");
		for (int k = 0; k < target.size(); ++k) { // 输出最小生成树
			Edge e = target.get(k);
			System.out.println(e.start + "-->" + e.end);
		}
	}	 
}

/*
 * start:起始顶点 end:结束顶点 weight:权值
 */
class Edge {
	public int start;
	public int end;
	public double weight;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值