普利姆算法--求最小生成树

在普里姆算法中,我们从一些根顶点开始的单个集群生成一颗最小生成树,主要思想与Dijkstra算法一些,属于贪心算法

算法思想

我们先初始定义一个顶点,然后在相邻的所有边中迭代算这一个最小权值的边 e = (u,v),将顶点u链接到初始点c之外的顶点v,之后将顶点v放到c中,并且一直重复知道完成,

算法分析

prim算法与dijksta类似,都比较依赖与一个适应性比较强的优先队列Q,我们最初将n放到q中,然后在取出操作,并且更新全部m的优先权作为算法的一部分,这些都是主要花费的世界,如果是一个基于堆的优先对立,每个操作的运行时间是O(log n),全部则是O((n+m)Log n),对于连图是O(m log n),未排序的则是O(n^2)

算法步骤

  1. 设G-(V,E)是连通网, T-(U,D)是最小生成树, v,U是顶点集合, E,D是边的集合

  2. 若从顶点u开始构造最小生成树,则从集合v中取出顶点u放入集合U中,标记顶点v的visited[u]-1

  3. 若集合U中顶点ui与集合v-U中的顶点vi之间存在边,则寻找这些边中权值最小的边,但不能构成回路,将顶点vj加入集合U中,将边(ui,vj)加入集合D中,标记visited[vij]-1

  4. 重复步骤2,直到U与v相等,即所有顶点都被标记为访问过,此时D中有n-1条边

  5. 提示:单独看步骤很难理解,我们通过代码来讲解,比较好理解

图解步骤

顶点a的领边是 a->b = 5, a->g = 2, a->c = 7,选择g
普利姆算法--求最小生成树_第1张图片
集合U有a->b = 5, a->c = 7,g->b = 3,g -> e = 4,故算g->b
普利姆算法--求最小生成树_第2张图片
g->b 已经访问过b了,a->b就没有了,集合U有,a->c = 7,b->d = 9,g -> e = 4,故算g->e
普利姆算法--求最小生成树_第3张图片

集合U有 a->c = 7, b->d = 9,e->f = 5,故算e - > f
普利姆算法--求最小生成树_第4张图片

集合U有 a->c = 7, b->d = 9,f ->d = 4,故算f->d

普利姆算法--求最小生成树_第5张图片
集合U有 a->c = 7, b->d = 9, e->c =8 故算a - >c
普利姆算法--求最小生成树_第6张图片

代码

public void prim(MGraph graph, int v){

    int visited[] = new int[graph.graphNodeCount];
    visited[v] = 1;
    int top1 = -1, top2 = -1;
    int minWeight = 10000; // 最大权值
    for(int k = 0;k < graph.graphNodeCount;k++){
        for (int i = 0; i < graph.graphNodeCount; i++) {
            for (int j = 0; j < graph.graphNodeCount; j++) {
                if (visited[i] == 1 && visited[j] == 0 && graph.weight[i][j] < minWeight) {
                    minWeight = graph.weight[i][j]; //替换最小权重
                    top1 = i;
                    top2 = j;
                }
            }
        }
        visited[top2] = 1;
        minWeight = 10000;

    }
}

你可能感兴趣的:(算法,数据结构,线性代数)