图-有权图-最小生成树

package k_graph.B_WeightedGraph.A_Mstw;


/**
 * 最小生成树
 * 
 * @有权无向,寻找距离最近的走遍所有点的路
 * 
 * @author Administrator
 *
 */
public class MSTWApp {
public static void main(String[] args) {
Graph theGraph = new Graph();
theGraph.addVertex('A');
theGraph.addVertex('B');
theGraph.addVertex('C');
theGraph.addVertex('D');
theGraph.addVertex('E');
theGraph.addVertex('F');


theGraph.addEdge(0, 1, 6);
theGraph.addEdge(0, 3, 4);
theGraph.addEdge(1, 2, 10);
theGraph.addEdge(1, 3, 7);
theGraph.addEdge(1, 4, 7);
theGraph.addEdge(2, 3, 8);
theGraph.addEdge(2, 4, 5);
theGraph.addEdge(2, 5, 6);
theGraph.addEdge(3, 4, 12);
theGraph.addEdge(4, 5, 7);
theGraph.mstw();
}
}package k_graph.B_WeightedGraph.A_Mstw;


/**
 * 优先级队列 数组实现
 * 
 * @author Administrator
 *
 */
public class PriorityQ {
private final int SIZE = 20;
private Edge[] queArray;
private int size;


public PriorityQ() {
queArray = new Edge[SIZE];
size = 0;
}


/**
* 插入边

* @param item
*/
public void insert(Edge item) {


int j;
// 获取索引
for (j = 0; j < size; j++)
if (item.distance >= queArray[j].distance)
break;
for (int k = size - 1; k >= j; k--)
queArray[k + 1] = queArray[k];


queArray[j] = item;
size++;
}


/**
* 删除指定的边

* @param n
*/
public void removeN(int n) {


for (int j = n; j < size - 1; j++)
queArray[j] = queArray[j + 1];
size--;
}


/**
* 查看边最小值

* @return
*/
public Edge peekMin() {


return queArray[size - 1];
}


/**
* 返回个数

* @return
*/
public int size() {


return size;
}


/**
* 查看是否为空

* @return
*/
public boolean isEmpty() {


return size == 0;
}


/**
* 查看指定的边

* @param n
* @return
*/
public Edge peekN(int n) {
return queArray[n];
}


/**
* 查询队列中到达findDex顶点边的索引

* @param findDex
* @return
*/
public int find(int findDex) {


int i = -1;
for (int k = 0; k < size; k++)
if (queArray[k].destVert == findDex) {
i = k;
break;
}
return i;
}


public Edge removeMin() {
return queArray[--size];
}
}package k_graph.B_WeightedGraph.A_Mstw;


public class Vertex {
public char label;
public boolean isInTree;// 是否在树中


public Vertex(char label) {
this.label = label;
this.isInTree = false;
}


}package k_graph.B_WeightedGraph.A_Mstw;


public class Graph {
private final int MAX_VERTS = 20;// 个数
private final int INFINIITY = 1000000;// 默认距离
private Vertex vertexList[];// 顶点数组
private int adjMat[][];// 关联边
private int nVerts;// 现在顶点个数
private int currentVerts;// 现在顶点
private PriorityQ thePQ;// 优先级队列
private int nTree;// 树个数


public Graph() {
vertexList = new Vertex[MAX_VERTS];
adjMat = new int[MAX_VERTS][MAX_VERTS];
nVerts = 0;
thePQ = new PriorityQ();
for (int i = 0; i < MAX_VERTS; i++)
for (int k = 0; k < MAX_VERTS; k++)
adjMat[i][k] = INFINIITY;
}


/**
* 添加顶点

* @param lab
*/
public void addVertex(char lab) {
vertexList[nVerts++] = new Vertex(lab);
}


/**
* 添加边长

* @param start
*            行
* @param end
*            列
* @param weight
*            distance 距离

*/
public void addEdge(int start, int end, int weight) {
adjMat[start][end] = weight;
adjMat[end][start] = weight;
}


public void displayVertex(int v) {
System.out.print(vertexList[v].label);
}


/**
* minimum spanning tree 最小生成树
*/
public void mstw() {
currentVerts = 0;// 现在顶点索引
while (nTree < nVerts - 1) {// 树个数小于顶点时循环
vertexList[currentVerts].isInTree = true;// 存放树中
nTree++;// 树个数增加
for (int i = 0; i < nVerts; i++) {// 一行中查找
// 源点和顶点相同,
if (i == currentVerts)
continue;
// 判断终点在不在树中
if (vertexList[i].isInTree)
continue;
int distance = adjMat[currentVerts][i];// 获取2边间隔
if (distance == INFINIITY)// 距离为默认值则跳过
continue;
putInPQ(i, distance);// 存放优先级队列中
}
// 优先级队列个数为0,则不流通图,退出
if (thePQ.size() == 0) {
System.out.println("循环图");
return;
}
Edge theEdge = thePQ.removeMin();// 删除最小边
int srcVert = theEdge.srcVert;
currentVerts = theEdge.destVert;// 设置现在的顶点索引
System.out.print(vertexList[srcVert].label);
System.out.print(vertexList[currentVerts].label + " ");
}
// isInTree重置
for (int i = 0; i < nVerts; i++) {
vertexList[i].isInTree = false;
}
}


/**
* 放入队列中

* @param newVert
* @param newDist
*/
public void putInPQ(int newVert, int newDist) {
int queueIndex = thePQ.find(newVert);// 查询队列中到达newVert顶点的边索引
if (queueIndex != -1) {
Edge tempEdge = thePQ.peekN(queueIndex);// 根据索引获得边
int oldDistance = tempEdge.distance;

// 此操作保证开始点到终点只有最小的边存在于队列
if (oldDistance > newDist) {// 比较距离之前的比现在的大的话,删除之前的,否则不添加。
thePQ.removeN(queueIndex);
Edge theEdge = new Edge(currentVerts, newVert, newDist);
thePQ.insert(theEdge);
}
} else {
Edge theEdge = new Edge(currentVerts, newVert, newDist);
thePQ.insert(theEdge);
}
}
}package k_graph.B_WeightedGraph.A_Mstw;


/**
 * 边
 * 
 * @author Administrator 
 *
 */ 
public class Edge {
public int srcVert;// 顶点开始边索引
public int destVert;// 顶点结尾边索引
public int distance;// 距离


public Edge(int srcVert, int destVert, int distance) {
super();
this.srcVert = srcVert;
this.destVert = destVert;
this.distance = distance;
}


}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值