package com.guge.test.graph;
/**
* 最小生成树
* Created by Guge on 2017/6/19.
*/
public class GraphW {
private final int MAX_SIZE=20;
private final int INFINITY=100000;
private Vertex[] vertexList;
private int[][] adjMat; //邻接矩阵
private int currentVert; //当前顶点
private PriorityQueue thePQ; //优先级队列
private int nTree; //最小生成树数量
private int nVerts;
public GraphW(){
vertexList=new Vertex[MAX_SIZE];
adjMat=new int[MAX_SIZE][MAX_SIZE];
for (int i = 0; i < MAX_SIZE; i++) {
for (int j = 0; j < MAX_SIZE; j++) {
adjMat[i][j]=INFINITY;
}
}
thePQ=new PriorityQueue();
nTree=0;
nVerts=0;
}
public void addVert(char vertex){
vertexList[nVerts++]=new Vertex(vertex);
}
public void addEdge(int start,int end,int weight){
adjMat[start][end]=weight;
adjMat[end][start]=weight;
}
public void displayVertex(int index){
System.out.print(vertexList[index].label);
}
/**
* 最小生成树
*/
public void mstw(){
currentVert=0;
while (nTree<nVerts-1){
vertexList[currentVert].isInTree=true;
nTree++;
for (int i = 0; i < nVerts; i++) { //添加邻边到优先级队列
if(i==currentVert)
continue;
if(vertexList[i].isInTree)
continue;
int distance=adjMat[currentVert][i];
if(distance==INFINITY)
continue;
putInPQ(i,distance);
}
if(thePQ.isEmpty()){
System.out.println("the graph is not connected");
return;
}
Edge item= thePQ.removeMin();
int source=item.srcVert;
int destVert=item.destVert;
currentVert=destVert;
System.out.print(vertexList[source].label);
System.out.print(vertexList[destVert].label);
System.out.print(" ");
}
for (int i = 0; i < nVerts; i++) {
vertexList[i].isInTree=false;
}
}
/**
* 插入优先级队列
* @param newVert
* @param distance
*/
public void putInPQ(int newVert,int distance){
int queueIndex=thePQ.findIndexByDest(newVert); //查找是否有到达当前顶点的边
if(queueIndex!=-1){
Edge old=thePQ.peekN(queueIndex);
if(old.distance>distance){ //如果队列中的边距离大于新插入的边的距离
thePQ.removeN(queueIndex); //删除队列中的边
Edge newEdge=new Edge(currentVert,newVert,distance);
thePQ.insert(newEdge);
}
}else { //直接插入新边
Edge newEdge=new Edge(currentVert,newVert,distance);
thePQ.insert(newEdge);
}
}
/**
* 边
*/
class Edge{
public int srcVert; //起点
public int destVert; //终点
public int distance; //距离
public Edge(int sv,int dv,int dis){
srcVert=sv;
destVert=dv;
distance=dis;
}
}
/**
* 顶点
*/
class Vertex{
public char label;
public boolean isInTree;
public Vertex(char label){
this.label=label;
isInTree=false;
}
}
/**
* 优先级队列
*/
class PriorityQueue{
private final int SIZE=20;
private Edge[] queueArr;
private int size;
public PriorityQueue(){
queueArr=new Edge[SIZE];
size=0;
}
public void insert(Edge item){
int i;
for (i = 0; i < size; i++) {
if(item.distance>=queueArr[i].distance)
break;
}
for (int j = size-1; j >=i ; j--) {
queueArr[j+1]=queueArr[j];
}
queueArr[i]=item;
size++;
}
public Edge removeMin(){
return queueArr[--size];
}
public Edge removeN(int n){
Edge temp=queueArr[n];
for (int i = n; i < size - 1; i++) {
queueArr[i]=queueArr[i+1];
}
size--;
return temp;
}
public Edge peek(){
return queueArr[size-1];
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public Edge peekN(int n){
return queueArr[n];
}
/**
* 通过目的顶点查找当前索引
* @param dest
* @return
*/
public int findIndexByDest(int dest){
for (int i = 0; i < size; i++)
if(queueArr[i].destVert==dest)
return i;
return -1;
}
}
}
class GraphWApp{
public static void main(String[] args) {
GraphW graphW=new GraphW();
graphW.addVert('A');
graphW.addVert('B');
graphW.addVert('C');
graphW.addVert('D');
graphW.addVert('E');
graphW.addVert('F');
graphW.addEdge(0,1,6); //AB 6
graphW.addEdge(0,3,4); //AD 4
graphW.addEdge(1,2,10); //BC 10
graphW.addEdge(1,3,7); //BD 7
graphW.addEdge(1,4,7); //BE 7
graphW.addEdge(2,3,8); //CD 8
graphW.addEdge(2,4,5); //CE 5
graphW.addEdge(2,5,6); //CF 6
graphW.addEdge(3,4,12); //DE 12
graphW.addEdge(4,5,7); //EF 7
System.out.println("最小生成树");
graphW.mstw();
System.out.println();
}
}
头疼