法一
代码
package kruskal;
import java.util.Arrays;
/**
* 解决最小生成树的另一种方法
*/
public class KruskalDemo {
public static void main(String[] args) {
char[] datas = new char[]{'A','B','C','D','E','F','G'};
int verxs = datas.length;
int max = Integer.MAX_VALUE;
int[][] weight = {
{0,12,max,max,max,16,14},
{12,0,10,max,max,7,max},
{max,10,0,3,5,6,max},
{max,max,3,0,4,max,max},
{max,max,5,4,0,2,8},
{16,7,6,max,2,0,9},
{14,max,max,max,8,9,0}
};
Graph graphs = new Graph(verxs,datas,weight);
//输出公交站
graphs.show();
// System.out.println("公交站的路线条数有" + graphs.weightLen);
/* System.out.println("所有边为" + Arrays.toString(graphs.edges));
graphs.edgeSort();*/
// System.out.println("排序后的边为" + Arrays.toString(graphs.edges));
graphs.minTree();
System.out.println("最小生成树为" + Arrays.toString(graphs.overEdges));
}
}
/**
* 生成公交站的方法
*/
class Graph{
int verxs;//顶点的个数
char[] datas;//顶点的代号
int[][] weight;//边的值
int weightLen;//边的条数
Edges[] edges;//边的集合数组
int[] ends;//用于存储顶点的尾节点
Edges[] overEdges;//用来存储已经成功加入的边(即最小树的边)
//构造方法
public Graph(int verxs, char[] datas, int[][] weight) {
this.verxs = verxs;
this.ends = new int[verxs];
this.datas = datas;
this.weight = weight;
for (int i = 0; i < verxs; i++) {//用以统计边的数量
for (int j = i + 1; j < verxs; j++) {
if (weight[i][j] != Integer.MAX_VALUE){
weightLen++;//边条数自增
}
}
}
this.edges = new Edges[weightLen];
alledges();//将所有的边加入到边的集合中
this.overEdges = new Edges[verxs - 1];//初始化一个储存结果的数组
}
public int findChar(char value){
int temp = -1;
for (int i = 0; i < datas.length; i++) {
if (datas[i] == value){
temp = i;
return temp;
}
}
return temp;
}
//生成最小生成树
public void minTree(){
//将边集合进行排序
edgeSort();
for (int i = 0; i < edges.length; i++) {
//获得顶点的尾结点
int p1 = findChar(edges[i].start);
int p2 = findChar(edges[i].end);
//获得尾结点
int m = getEnd(ends,p1);
int n = getEnd(ends,p2);
if (m != n){//不连通的情况
ends[m] = n;
addEdges(edges[i]);
// System.out.println(edges[i]);
}
}
}
//寻找一个节点的尾节点,获取下标为i的顶点的终点
public int getEnd(int[] ends,int i){
while (ends[i] != 0){
i = ends[i];
}
return i;
}
//将判断结束的边(符合条件的边)加入到overEdges中
public void addEdges(Edges e){
for (int i = 0; i < overEdges.length; i++) {
if (overEdges[i] == null){
overEdges[i] = e;
break;
}
}
}
//写一个边的集合
public void alledges(){
for (int i = 0; i < verxs; i++) {//用以添加边
for (int j = i + 1; j < verxs; j++) {
if (weight[i][j] != Integer.MAX_VALUE){
for (int k = 0; k < edges.length; k++) {
if (edges[k] == null){
edges[k] = new Edges(datas[i],datas[j],weight[i][j]);
break;
}
}
}
}
}
}
//对边进行排序
public void edgeSort(){
for (int i = 0; i < edges.length; i++) {
for (int j = 0; j < edges.length - 1 - i; j++) {
if (edges[j].value > edges[j + 1].value){
int temp = edges[j].value;
edges[j].value = edges[j + 1].value;
edges[j + 1].value = temp;
}
}
}
}
/**
* 将数据展示出来
*/
public void show(){
System.out.println("公交站的值为");
for (int i = 0; i < verxs; i++) {
for (int j = 0; j < verxs; j++) {
System.out.printf("%-12d\t",weight[i][j]);
}
System.out.println();
}
}
}
class Edges{
char start;//边的起始顶点
char end;//边的终点
int value;//边对应的值
public Edges(char start, char end, int value) {
this.start = start;
this.end = end;
this.value = value;
}
@Override
public String toString() {
return "edges{" +
"<" + start +
",>" + end +
"-->" + value +
'}';
}
}
法二
代码
package prim;
import java.util.Arrays;
/**
* 最小生成树的生成
*/
public class PrimDemo {
public static void main(String[] args) {
char[] datas = new char[]{'A','B','C','D','E','F','G'};
int verxs = datas.length;
int max = 10000;
int[][] weight = {
{max,5,7,max,max,max,2},
{5,max,max,9,max,max,3},
{7,max,max,max,8,max,max},
{max,9,max,max,max,4,max},
{max,max,8,max,max,5,4},
{max,max,max,4,5,max,6},
{2,3,max,max,4,6,max}
};
Graph graph = new Graph(verxs,datas,weight);
graph.show();
graph.minTree(1);
}
}
/**
* 生成村庄的类
*/
class Graph{
public int verxs;//顶点的个数
public char[] datas;//顶点的代号
public int[][] weight;//边的值
public Graph(int verxs, char[] datas, int[][] weight) {
this.verxs = verxs;
this.datas = datas;
this.weight = weight;
}
public void show(){
System.out.println("村庄的值为");
for (int[] data:weight) {
System.out.println(Arrays.toString(data));
}
}
/**
* //生成最小生成树的方法
* @param v 表示开始遍历的节点的位置
*/
public void minTree(int v){
//使用一个boolean数组表示对应的节点是否被添加,false表示没有被添加
boolean[] visited = new boolean[this.verxs];
//将起始节点加入
visited[v] = true;
//行列的命名
int row = 0;
int line = 0;
for (int i = 0; i < verxs - 1; i++) {
int minData = 10000;
for (int j = 0; j < verxs; j++) {//表示的是已经被添加过的
for (int k = 0; k < verxs; k++) {//表示还没有被添加过的
if (visited[j] && !visited[k] && minData > weight[j][k]){
row = j;
line = k;
minData = weight[j][k];
}
}
}
// System.out.println(line);
System.out.println("节点" + datas[row] + "到节点" +
datas[line] + "的值为" + minData);
visited[line] = true;
}
}
}