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;
}
My_Graph prim
最新推荐文章于 2024-08-14 18:01:26 发布