普里姆算法(prim)的实现

普里姆算法按照以下步骤逐步扩大树中所含顶点的数目,直到遍及连通图的所有顶点:

  1. 输入:一个加权连通图,其中顶点集合为V,边集合为E;
  2. 初始化:Vnew = {x},其中x为集合V中的任一节点(起始点),Enew = {};
  3. 重复下列操作,直到Vnew = V:
    1. 在集合E中选取权值最小的边(u, v),其中u为集合Vnew中的元素,而v则不是(如果存在有多条满足前述条件即具有相同权值的边,则可任意选取其中之一);
    2. 将v加入集合Vnew中,将(u, v)加入集合Enew中;
  4. 输出:使用集合Vnew和Enew来描述所得到的最小生成树。

实现:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Prim {

	public static List<Vertex> vertexList = new ArrayList<Vertex>();// 结点集
	public static List<Edge> EdgeQueue = new ArrayList<Edge>();// 边集
	public static List<Vertex> newVertex = new ArrayList<Vertex>();// 已经 访问过的结点

	public static void main(String[] args) {
		primTree();

	}

	/**
	 * 
	 *  构建图
	 * 
	 **/
	public static void buildGraph() {
		Vertex v1 = new Vertex("a");
		Prim.vertexList.add(v1);
		Vertex v2 = new Vertex("b");
		Prim.vertexList.add(v2);
		Vertex v3 = new Vertex("c");
		Prim.vertexList.add(v3);
		Vertex v4 = new Vertex("d");
		Prim.vertexList.add(v4);
		Vertex v5 = new Vertex("e");
		Prim.vertexList.add(v5);
		addEdge(v1, v2, 6);
		addEdge(v1, v3, 7);
		addEdge(v2, v3, 8);
		addEdge(v2, v5, 4);
		addEdge(v2, v4, 5);
		addEdge(v3, v4, 3);
		addEdge(v3, v5, 9);
		addEdge(v5, v4, 7);
		addEdge(v5, v1, 2);
		addEdge(v4, v2, 2);
	}

	/**
	 * 
	 *  构建边
	 * 
	 **/
	public static void addEdge(Vertex a, Vertex b, int w) {
		Edge e = new Edge(a, b, w);
		Prim.EdgeQueue.add(e);
	}

	/**
	 * 
	 *  prim算法寻找最小生成树的实现
	 * 
	 **/
	public static void primTree() {
		buildGraph();
		Vertex start = vertexList.get(0);
		newVertex.add(start);
		for (int n = 0; n < vertexList.size(); n++) {
			Vertex temp = new Vertex(start.key);
			Edge tempedge = new Edge(start, start, 1000);
			for (Vertex v : newVertex) {
				for (Edge e : EdgeQueue) {
					//如果边开始结点等于当前结点,并且边的终点等没有被访问过
					if (e.start == v && !containVertex(e.end)) {
						//得出最小权值
						if (e.key < tempedge.key) {   
							temp = e.end;
							tempedge = e;
						}

					}
				}
			}
			newVertex.add(temp);
		}
		
		Iterator it = newVertex.iterator();
		while (it.hasNext()) {
			Vertex v = (Vertex) it.next();
			System.out.println(v.key);
		}
	}

	/**
	 * 
	 *  判断传入的结点是否是已经被访问过的结点
	 * 
	 **/
	public static boolean containVertex(Vertex vte) {
		for (Vertex v : newVertex) {
			if (v.key.equals(vte.key))
				return true;
		}
		return false;
	}
}

/**
 * 
 *  结点类
 *
 **/
class Vertex {
	String key;    //结点名

	Vertex(String key) {
		this.key = key;
	}
}

/**
 * 
 *  边类
 *
 **/
class Edge {
	Vertex start;   //边的开始结点
	Vertex end;     //边的终点结点
	int key;        //边的权值

	Edge(Vertex start, Vertex end, int key) {
		this.start = start;
		this.end = end;
		this.key = key;

	}
}


声明:本代码不是自己编写,来自维基百科,本人只是做了点修改。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值