图的KRUSKAL算法是用以求解最小生成树的一种有效算法,每次从待选的边中选出最短的那一条边,加入到已有的树中,读者可以与PRIM算法相比较他们之间的异同,下面是代码,该代码利用堆排序以求能在较短时间内取出最短的那一条边。
package oj;
class Edge{
int x1;
int x2;
int len;
public Edge(int x1, int x2, int len) {
this.x1 = x1;
this.x2 = x2;
this.len = len;
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getX2() {
return x2;
}
public void setX2(int x2) {
this.x2 = x2;
}
public int getLen() {
return len;
}
public void setLen(int len) {
this.len = len;
}
}
public class KRUSKAL {
public static void kruskal(Edge2[] edges,int[] point){
preSortByLen(edges);
int[] p=makeSet(point);
int[] rank=initRank(point);
Edge2[] T=new Edge2[point.length-1]; //最小生成树的边数是定点数-1
int k=0; //该指针用来表示edges中的下一条边
int t=0;
while(t<point.length-1){
Edge2 e=edges[k++];
if(find(e.getX1(),p)!=find(e.getX2(),p)){
T[t++]=e;
union(e.getX1(),e.getX2(),p,rank);
}
}
int sum=0;
for(int j=0;j<T.length;j++){
System.out.println(j+1+" :"+T[j].getLen());
}
}
//初始化建堆,对每个顶点来说他的父节点是他本身
public static int[] makeSet(int[] point){
int[] p=new int[point.length];
for(int i=0;i<point.length;i++){
p[point[i]]=point[i];
}
return p;
}
public static int find(int x,int[] p){
int y=x;
while(p[y]!=y){
y=p[y];
}
int root=y;
return root;
}
public static int[] initRank(int[] point){
int[] rank=new int[point.length];
for(int i=0;i<point.length;i++){
rank[point[i]]=1;
}
return rank;
}
public static void union(int x,int y,int p[],int rank[]){
int r1=find(x,p);
int r2=find(y,p);
if(rank[r1]<=rank[r2]){
p[r1]=r2;
if(rank[r1]==rank[r2]){
rank[r2]++;
}
}
else{
p[r2]=r1;
}
}
public static void preSortByLen(Edge2[] edges){
int len=edges.length;
for(int i=1;i<=len-1;i++){
for(int j=edges.length-1;j>=i;j--){
if(edges[j].getLen()<edges[j-1].getLen()){
Edge2 temp=edges[j-1];
edges[j-1]=edges[j];
edges[j]=temp;
}
}
}
}
public static void main(String args[]){
Edge2 e1=new Edge2(0,1,1);
Edge2 e2=new Edge2(0,2,2);
Edge2 e3=new Edge2(1,2,6);
Edge2 e4=new Edge2(1,3,11);
Edge2 e5=new Edge2(2,3,9);
Edge2 e6=new Edge2(2,4,13);
Edge2 e7=new Edge2(3,4,7);
Edge2 e8=new Edge2(3,5,3);
Edge2 e9=new Edge2(4,5,4);
Edge2 edges[]={e1,e2,e3,e4,e5,e6,e7,e8,e9};
int[] point=new int[6];
for(int i=0;i<point.length;i++){
point[i]=i;
}
kruskal(edges,point);
}
}