使用临界矩阵
定义类N
属性中包含起始点和终点以及边的权值
class N{
int power;
int s,e;
public N(int power,int s,int e)
{
this.s=s;
this.e=e;
this.power=power;
}
}
定义小根堆
class MinHeap1{
//存数据
N[]data;
//堆的大小
int heapsize=0;
//构造函数
public MinHeap1(int length)
{
data=new N[length];
}
//添加元素时,我们会加入到最后一个位置,需要进行上浮的操作维护堆
//添加元素
public boolean add(N t)
{
if(heapsize== data.length)
{
data=Arrays.copyOf(data,data.length*2);
}
data[++heapsize]=t;
int now=heapsize;
while(now>1)
{
int next=now/2;
if(data[now].power>=data[next].power)
break;
swap(now,next);
now=next;
}
return true;
}
//出堆
public N poll()
{
N res=data[1];
//将最后一个元素放到开头的位置,进行下沉的操作,维护小根堆的性质
data[1]=data[heapsize];
heapsize--;
int now=1;
while(now*2<=heapsize)
{
int next=2*now;
if(next+1<heapsize&&data[next+1].power<data[next].power)
next++;
if(data[next].power>=data[now].power)
break;
swap(next,now);
now=next;
}
return res;
}
//交换元素
public void swap(int i,int j)
{
N x=this.data[i];
data[i]=data[j];
data[j]=x;
}
//判断堆是否为空
public boolean isEmpty()
{
return heapsize==0;
}
}
主要代码
public static void Prim() {
//记录经过的点
List<Integer>res=new ArrayList<>();
//一个存点的集合
Set<Integer>set=new HashSet<>();
//记录经历边的权值
List<Integer>k=new ArrayList<>();
Random random=new Random();
//java原生优先队列
//PriorityQueue<N>queue=new PriorityQueue<>((t1,t2)->{return t1.power- t2.power;});
//自定义堆
MinHeap1 queue=new MinHeap1(100);
//随机取一个点
int p=random.nextInt(a.length);
//将初始点添加到res中
res.add(p);
set.add(p);
//优先队列的初始化
for(int i=0;i<a[p].length;i++)
{
//0代表自己max为无穷
if(a[p][i]!=0&&a[p][i]!=max)
queue.add(new N(a[p][i],p,i));
}
//要保证set包含每一个点
while(set.size()<a.length)
{
//出队
N t=queue.poll();
//如果包含所能到达的目标点证明有回路直接略过
if(set.contains(t.e)&&set.contains(t.s))
continue;
//不包含目标点
if(!set.contains(t.e))
{
k.add(t.power);
//将他加入集合中
set.add(t.e);
res.add(t.e);
//将目标点作为起始点,添加对应能取的目标点
for(int i=0;i<a[t.e].length;i++)
{
if(a[t.e][i]!=0&&a[t.e][i]!=max)
queue.add(new N(a[t.e][i],t.e,i));
}
}
}
System.out.println("最小生成树为:");
for(int i:res)
System.out.print(i+"->");
System.out.println();
System.out.println("对应边的值");
for(int i:k)
{
System.out.print(i+" ");
}
}
}
测试
//测试
public final static int max=Integer.MAX_VALUE;
public static int [][]a={
{0,1,5,6,max,max},
{1,0,8,max,4,max},
{5,8,0,7,2,max},
{6,max,7,0,max,3},
{max,4,2,max,0,9},
{max,max,max,3,9,0},
};
public static void main(String[] args) {
Prim();
}


1万+

被折叠的 条评论
为什么被折叠?



