代码实现
上面分析了逻辑实现。下面我们用代码简单实现上述的算法。
prim
package 图论;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
public class prim {
public static void main(String[] args) {
int minlength=0;
int max=66666;
String cityname[]= {"北京","武汉","南京","上海","杭州","广州","深圳"};
int city[][]= {
{ max, 8, 7, max, max, max, max },
{ 8, max,6, max,9, 8,max },
{ 7, 6, max, 3,4, max,max },
{ max, max,3, max,2, max,max },
{ max, 9,4, 2,max, max,10 },
{ max, 8,max, max,max, max,2 },
{ max, max,max, max,10,2,max }
};
boolean istrue[]=new boolean[7];
Queue<side>q1=new PriorityQueue<side>(new Comparator<side>() {
public int compare(side o1, side o2) {
return o1.lenth-o2.lenth;
}
});
for(int i=0;i<7;i++)
{
if(city[2][i]!=max)
{
istrue[2]=true;
q1.add(new side(city[2][i], 2, i));
}
}
while(!q1.isEmpty())
{
side newside=q1.poll();
if(istrue[newside.point1]&&istrue[newside.point2])
{
continue;
}
else {
if(!istrue[newside.point1])
{
istrue[newside.point1]=true;
minlength+=city[newside.point1][newside.point2];
System.out.println(cityname[newside.point1]+" "+cityname[newside.point2]+" 联通");
for(int i=0;i<7;i++)
{
if(!istrue[i])
{
q1.add(new side(city[newside.point1][i],newside.point1,i));
}
}
}
else {
istrue[newside.point2]=true;
minlength+=city[newside.point1][newside.point2];
System.out.println(cityname[newside.point2]+" "+cityname[newside.point1]+" 联通");
for(int i=0;i<7;i++)
{
if(!istrue[i])
{
q1.add(new side(city[newside.point2][i],newside.point2,i));
}
}
}
}
}
System.out.println(minlength);
}
static class side
{
int lenth;
int point1;
int point2;
public side(int lenth,int p1,int p2) {
this.lenth=lenth;
this.point1=p1;
this.point2=p2;
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
输出结果:
Kruskal:
package 图论;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;
import 图论.prim.side;
public class kruskal {
static int tree[]=new int[10];
public static void init() {
for(int i=0;i<10;i++)
{
tree[i]=-1;
}
}
public static int search(int a)
{
if(tree[a]>0)
{
return tree[a]=search(tree[a]);
}
else
return a;
}
public static void union(int a,int b)
{
int a1=search(a);
int b1=search(b);
if(a1==b1) {
}
else {
if(tree[a1]<tree[b1])
{
tree[a1]+=tree[b1];
tree[b1]=a1;
}
else
{
tree[b1]+=tree[a1];
tree[a1]=b1;
}
}
}
public static void main(String[] args) {
init();
int minlength=0;
int max=66666;
String cityname[]= {"北京","武汉","南京","上海","杭州","广州","深圳"};
boolean jud[][]=new boolean[7][7];
int city[][]= {
{ max, 8, 7, max, max, max, max },
{ 8, max,6, max,9, 8,max },
{ 7, 6, max, 3,4, max,max },
{ max, max,3, max,2, max,max },
{ max, 9,4, 2,max, max,10 },
{ max, 8,max, max,max, max,2 },
{ max, max,max, max,10,2,max }
};
boolean istrue[]=new boolean[7];
Queue<side>q1=new PriorityQueue<side>(new Comparator<side>() {
public int compare(side o1, side o2) {
return o1.lenth-o2.lenth;
}
});
for(int i=0;i<7;i++)
{
for(int j=0;j<7;j++)
{
if(!jud[i][j]&&city[i][j]!=max)
{
jud[i][j]=true;jud[j][i]=true;
q1.add(new side(city[i][j], i, j));
}
}
}
while(!q1.isEmpty())
{
side newside=q1.poll();
int p1=newside.point1;
int p2=newside.point2;
if(search(p1)!=search(p2))
{
union(p1, p2);
System.out.println(cityname[p1]+" "+cityname[p2]+" 联通");
minlength+=newside.lenth;
}
}
System.out.println(minlength);
}
static class side
{
int lenth;
int point1;
int point2;
public side(int lenth,int p1,int p2) {
this.lenth=lenth;
this.point1=p1;
this.point2=p2;
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
输出结果
总结
最小生成树算法理解起来也相对简单,实现起来也不是很难。Kruskal和Prim主要是贪心算法的两种角度。一个从整体开始找最小边,遇到关联不断合并,另一个从局部开始扩散找身边的最小不断扩散直到生成最小生成树。在学习最小生成树之前最好学习一下dijkstra算法和并查集,这样在实现起来能够快一点,清晰一点。
文章转自公众号:bigsai