prim的时间复杂度java中_lazy Prim中的一个小小的优化和时间复杂度分析

老师的代码中对于循环结束的情况是当堆中不为空的时候

我的实现:

优化了时间复杂度? 变成了O((V-1)logE), 这个时间复杂度对吗?如果对的话不就是比O(ElogV)还快了吗?毕竟边的个数是一定大于等于顶点的个数的

public class Prim {

private Graph graph;// 要获取最小生成树的图

private PriorityQueue minHeap;// 最小堆, 优先队列, Java自带的优先队列是最小堆实现的

private ArrayList minSpanningTree;// 最小生成树的所有边

private boolean[]visited;// 顶点是否已经访问过

public Prim (Graph extends Comparable>> graph) {

this.graph = graph;

this.minHeap = new PriorityQueue();

this.minSpanningTree = new ArrayList();

this.visited = new boolean[graph.getPeak()];

for (int i = 0; i < visited.length; i++) {

visited[i] = false;

}

generateMinSpanningTree();

}

private void generateMinSpanningTree () {

// 从树的原顶点开始出发查找

int index = 0;

// 当所有顶点都被遍历之后, 最小生成树也就找到了, 边的数量应该是顶点的数量减一

while (minSpanningTree.size() < graph.getPeak() - 1) {

// 对该顶点进行迭代, 将其所有边都压入最小堆中

Iterators iterator = graph.iterator(index);

while (!iterator.end()) {

Edge next = iterator.next();

// 只将index顶点到一个未访问过的顶点的边压入最小堆

if (!visited[next.getToPeak()]) {

minHeap.add(next);

}

}

// 设置该顶点为已经访问过的, 这样下次其它顶点在迭代的时候就会忽略那些顶点到index的边

visited[index] = true;

// 此时取出最小的边, 如果这个最小边的两个顶点都被访问过了, 那么就提取下一个最小边

// 直到一个被访问一个没被访问则才是横切边, 该边就是最小生成树中的一条边, 并放入最小生成树中

Edge minEdge;

while (true) {

minEdge = minHeap.remove();

if (visited[minEdge.getFromPeak()] && visited[minEdge.getToPeak()]) {

continue;

}

break;

}

minSpanningTree.add(minEdge);

// 将index设置为该最小边中没被访问过的顶点

index = visited[minEdge.getToPeak()] == true ? minEdge.getFromPeak() : minEdge.getToPeak();

}

}

public ArrayList getMinSpanningTree () {

return minSpanningTree;

}

}

下面是边的类

public class Edge> implements Comparable>{

// 对于from, to来说, 只有在有向图的时候其意义才会不同

private int from;//表示边的第一端

private int to;// 表示边的第二端

private T weight;// 边的权重, 用泛型表示, 因为可以是整型, 可以是浮点型

public Edge (int from, int to, T weight) {

this.from = from;

this.to = to;

this.weight = weight;

}

public void setWeight (T weight) {

this.weight = weight;

}

public int getToPeak () {

return to;

}

public int getFromPeak () {

return from;

}

@Override

public String toString () {

return "{from: "+ from + ", to: "+ to + ", weight: " + weight +"}";

}

@Override

public int compareTo(Edge o) {

if (o == null) {

throw new IllegalArgumentException("Edge of o does not exist");

}

return weight.compareTo(o.weight);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值