X Tutup
Skip to content

Commit c3aae55

Browse files
author
yumengtao
committed
Prim算法
1 parent de4a8a7 commit c3aae55

File tree

6 files changed

+71535
-22
lines changed

6 files changed

+71535
-22
lines changed

src/com/zejian/structures/Graph/WeightGraph/LazyPrimMST.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public LazyPrimMST(WeightGraph graph){
2525

2626
visited = new boolean[graph.V()];
2727
minHeap = new MinHeap<Edge<Weight>>(graph.E());
28-
mst = new ArrayList<>(graph.V());
28+
mst = new ArrayList<Edge<Weight>>(graph.V());
2929

3030
//从第一个顶点开始访问
3131
visit(graph,0);
@@ -80,11 +80,11 @@ public List<Edge<Weight>> getMstEdgeList(){
8080
public static void main(String[] args){
8181
String filename = "weighttestG3.txt";
8282

83-
WeightSparseGraph<Double> weightSparseGraph = new WeightSparseGraph<>(8,false);
83+
WeightSparseGraph<Double> weightSparseGraph = new WeightSparseGraph<Double>(8,false);
8484
weightSparseGraph.readGraph(filename);
8585
weightSparseGraph.show();
8686

87-
LazyPrimMST<Double> lazy = new LazyPrimMST<>(weightSparseGraph);
87+
LazyPrimMST<Double> lazy = new LazyPrimMST<Double>(weightSparseGraph);
8888
System.out.println("总权值是:"+lazy.mstWeight());
8989
for (int i = 0; i <lazy.getMstEdgeList().size() ; i++) {
9090
System.out.println("e:"+lazy.getMstEdgeList().get(i));

src/com/zejian/structures/Graph/WeightGraph/PrimMST.java

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,111 @@
22

33
import com.zejian.structures.heap.IndexMinPQ;
44

5+
import java.util.ArrayList;
56
import java.util.List;
7+
import java.util.Observable;
68

79
/**
810
* Created by zejian on 2018/1/30.
911
* Blog : http://blog.csdn.net/javazejian [原文地址,请尊重原创]
1012
* 优化版的最小生成树算法
13+
* 时间复杂度 (V*LogV+E*LogV) = E*LogV
1114
* 利用最小索引堆
1215
*/
1316
public class PrimMST<Weight extends Number & Comparable<Weight>> {
1417

15-
private IndexMinPQ<Weight> pq;//最小索引堆,只存储权值更小的边,不会存放所有边
18+
private IndexMinPQ<Weight> pq;//最小索引堆,只存储权值更小的边,不会存放所有边
1619
private boolean marked[];//标记数组, 在算法运行过程中标记节点i是否被访问
1720
private Edge edgeTo[];//访问的点所对应的边, 因为索引堆中没存放具体边信息
1821
private List<Edge<Weight>> mst; // 最小生成树所包含的所有边
19-
private Number mWeight; //最小生成树的总权值
22+
private Number mstWeight; //最小生成树的总权值
2023

24+
public PrimMST(WeightGraph G) {
25+
assert G != null;
26+
pq = new IndexMinPQ<Weight>(G.V());
27+
marked = new boolean[G.V()];
28+
edgeTo = new Edge[G.V()];
29+
mst = new ArrayList<Edge<Weight>>();
30+
31+
for (int i = 0; i < G.V(); i++) {
32+
edgeTo[i] = null;
33+
}
34+
35+
36+
//prim算法
37+
visited(G, 0);
38+
while (!pq.isEmpty()) {
39+
int x = pq.deleteMin();
40+
if (edgeTo[x] != null) {
41+
mst.add(edgeTo[x]);
42+
visited(G,x);
43+
}
44+
}
45+
46+
47+
// 计算最小生成树的权值
48+
mstWeight = mst.get(0).wt();
49+
for( int i = 1 ; i < mst.size() ; i ++ )
50+
mstWeight = mstWeight.doubleValue() + mst.get(i).wt().doubleValue();
51+
52+
}
53+
54+
private void visited(WeightGraph graph, int v) {
55+
assert !marked[v];
56+
57+
marked[v] = true; //设置访问标志
58+
59+
//遍历邻边
60+
for (Object o : graph.adj(v)) {
61+
Edge<Weight> e = (Edge<Weight>) o;
62+
63+
int w = e.other(v);
64+
// 如果边的另一端点已被访问,跳过该顶点
65+
if (marked[w]) continue;
66+
// 如果从没有考虑过这个端点, 直接将这个端点和与之相连接的边加入索引堆
67+
if (edgeTo[w] == null) {
68+
edgeTo[w] = e;
69+
pq.insert(w, e.wt());
70+
}
71+
//如果曾经考虑这个端点, 但现在的边比之前考虑的边更短, 则进行替换
72+
else if (edgeTo[w] != null && edgeTo[w].compareTo(e) > 0) {
73+
edgeTo[w] = e;
74+
pq.change(w, e.wt());
75+
}
76+
77+
}
78+
}
79+
80+
/**
81+
* 返回最小生成树的所有边
82+
* @return
83+
*/
84+
public List<Edge<Weight>> getMstEdgeList(){
85+
return mst;
86+
}
87+
88+
/**
89+
* 返回最小生成树的权值
90+
* @return
91+
*/
92+
public Number mstWeight(){
93+
return mstWeight;
94+
}
95+
96+
97+
// 测试 Prim
98+
public static void main(String[] args) {
99+
String filename = "testWG1.txt";
100+
WeightSparseGraph<Double> wSparseGraph = new WeightSparseGraph<Double>(8,false);
101+
wSparseGraph.readGraph(filename);
102+
wSparseGraph.show();
103+
104+
PrimMST<Double> primMst = new PrimMST<Double>(wSparseGraph);
105+
List<Edge<Double>> mstList = primMst.getMstEdgeList();
106+
for( int i = 0 ; i < mstList.size() ; i ++ )
107+
System.out.println(mstList.get(i));
108+
System.out.println("The MST weight is: " + primMst.mstWeight());
109+
System.out.println();
110+
}
21111

22112
}

0 commit comments

Comments
 (0)
X Tutup