【0】README

0.1) 本文总结于 数据结构与算法分析, 源代码均为原创, 旨在 理解Prim算法的idea 并用 源代码加以实现;
0.2)最小生成树的基础知识,参见 http://blog.csdn.net/pacosonswjtu/article/details/49947085


【1】Prim算法相关

1.1)计算最小生成树的一种方法是使其连续地一步一步长成。在每一步, 都要吧一个节点当做根并往上加边,这样也就把相关联的顶点加到增长中的树上;
1.2)在算法中的任一时刻, 我们都可以看到一个已经添加到树上的顶点集, 而其余顶点尚未加到这颗树中。此时, 算法在每一阶段都可以通过选择边(u, v),使得(u, v)的值是所有u 在树上但v不在树上的边的值中的最小者, 而找出一个新的顶点并吧它添加到这颗树中;
1.3)具体步骤概括为:

  • step1)给定一个顶点为根节点;
  • step2)每一步加一条边和一个顶点; (这也迎合了 顶点个数-边个数=1 );

1.4)看个荔枝:

对上图的分析(Analysis):
A1)可以看到, 其实Prim算法基本上和求最短路径的 Dijkstra算法一样, 因此和前面一样,我们对每一个顶点保留值 Dv和Pv 以及一个指标,指示该顶点是已知的还是未知的。这里,Dv是连接v 到已知顶点的最短边的权, 而 Pv则是导致Dv改变的最后的顶点。
A2)算法的其余部分一样, 唯一不同的是: 由于Dv的定义不同, 因此它的更新法则不一样。事实上,Prim算法的更新法则比 Dijkstra算法简单:在每一个顶点v被选取后, 对于每一个与 v 邻接的未知的w, Dw=min(Dw, Cw,v);

对上图的分析(Analysis):
A1)该算法整个的实现实际上和 Dijkstra算法的实现是一样的, 对于 Dijkstra算法分析所做的每一件事都可以用到这里。 不过要注意, Prim算法是在无向图上运行的, 因此当编写代码的时候要记住要吧每一条变都要放到两个邻接表中。
A2)不用堆时的运行时间为O(|V|^2), 它对于稠密图来说是最优的; 使用二叉堆的运行时间为 O(|E|log|V|), 它对于稀疏图是一个好的界限;


【2】source code + printing results(将我的代码打印结果 同 上图中的手动模拟的prim算法的结果进行比较,你会发现, 它们的结果完全相同,这也证实了我的代码的可行性)

2.1)download source code: https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter9/p237_prim
2.2)source code at a glance(for complete code , please click the given link above):

#include "prim.h"//allocate the memory for initializing unweighted table
WeightedTable *initWeightedTable(int size)
{   WeightedTable* table;int i;table = (WeightedTable*)malloc(sizeof(WeightedTable) * size);if(!table){Error("out of space ,from func initWeightedTable");return NULL;}for(i = 0; i < size; i++){table[i] = makeEmptyWeightedTable();        if(!table[i])return NULL;}return table;
} // allocate the memory for every element in unweighted table
WeightedTable makeEmptyWeightedTable()
{WeightedTable element;element = (WeightedTable)malloc(sizeof(struct WeightedTable));if(!element){Error("out of space ,from func makeEmptyWeightedTable");return NULL;}   element->known = 0; // 1 refers to accessed , also 0 refers to not accessedelement->distance = MaxInt;element->path = -1; // index starts from 0 and -1 means the startup vertex unreaches other vertexsreturn element;
}// allocate the memory for storing index of  vertex in heap and let every element -1
int *makeEmptyArray(int size)
{int *array;int i;array = (int*)malloc(size * sizeof(int));if(!array){Error("out of space ,from func makeEmptyArray");return NULL;}       for(i=0; i<size; i++)array[i] = -1;return array;
}//computing the unweighted shortest path between the vertex under initIndex and other vertexs
void prim(AdjTable* adj, int size, int startVertex, BinaryHeap bh)
{       int adjVertex;  int tempDistance;WeightedTable* table;int vertex;     AdjTable temp;  Distance tempDisStruct;int *indexOfVertexInHeap;int indexOfHeap;table = initWeightedTable(size);        tempDisStruct = makeEmptyDistance();indexOfVertexInHeap = makeEmptyArray(size);tempDisStruct->distance = table[startVertex-1]->distance;tempDisStruct->vertexIndex = startVertex-1;insert(tempDisStruct, bh, indexOfVertexInHeap); // insert the (startVertex-1) into the binary heap  table[startVertex-1]->distance = 0;// update the distance table[startVertex-1]->path = 0;// update the path of starting vertexwhile(!isEmpty(bh)){       vertex = deleteMin(bh, indexOfVertexInHeap).vertexIndex; // return the minimal element in binary heap//printBinaryHeap(bh);table[vertex]->known = 1; // update the vertex as accessed, also let responding known be 1temp = adj[vertex]->next;while(temp){adjVertex = temp->index; if(table[adjVertex]->known == 1) // judge whether table[adjVertex]->known is 1 or not{temp = temp->next;continue;}//tempDistance = table[vertex]->distance + temp->weight; // update the distancetempDistance = temp->weight;if(tempDistance < table[adjVertex]->distance){table[adjVertex]->distance = tempDistance;table[adjVertex]->path = vertex; //update the path of adjVertex, also responding path evaluated as vertex                           // key, we should judge whether adjVertex was added into the binary heap                //if true , obviously the element has been added into the binary heap(so we can't add the element into heap once again)if(indexOfVertexInHeap[adjVertex] != -1) {indexOfHeap = indexOfVertexInHeap[adjVertex];bh->elements[indexOfHeap]->distance = tempDistance; // update the distance of corresponding vertex in binary heap}else // if not ture{tempDisStruct->distance = table[adjVertex]->distance;tempDisStruct->vertexIndex = adjVertex;insert(tempDisStruct, bh, indexOfVertexInHeap); // insert the adjVertex into the binary heap}}            temp = temp->next;      }       printPrim(table, size, startVertex);        printBinaryHeap(bh);printf("\n");}       printf("\n");
} //print unweighted table
void printPrim(WeightedTable* table, int size, int startVertex)
{int i;  char *str[4] = {"vertex","known","distance","path"};printf("\n\t === storage table related to Prim alg as follows: === ");  printf("\n\t %6s%6s%9s%5s", str[0], str[1], str[2], str[3]);    for(i=0; i<size; i++){       if(i != startVertex-1 && table[i]->path!=-1) printf("\n\t %-3d   %3d   %5d      v%-3d  ", i+1, table[i]->known, table[i]->distance, table[i]->path+1);else if(table[i]->path == -1)printf("\n\t %-3d   %3d   %5d      %-3d  ", i+1, table[i]->known, table[i]->distance, table[i]->path);elseprintf("\n\t *%-3d  %3d   %5d      %-3d  ", i+1, table[i]->known, table[i]->distance, 0);}
}int main()
{ AdjTable* adj;  BinaryHeap bh;int size = 7;int capacity;int i;int j;  int startVertex;int adjTable[7][7] = {{0, 2, 4, 1, 0, 0, 0},{2, 0, 0, 3, 10, 0, 0},{4, 0, 0, 2, 0, 5, 0},{1, 3, 2, 0, 7, 8, 4},{0, 10, 0, 7, 0, 0, 6},{0, 0, 5, 8, 0, 0, 1},{0, 0, 0, 4, 6, 1, 0},};printf("\n\n\t ====== test for Prim alg finding weighted shortest path from adjoining table ======\n");adj = initAdjTable(size);       printf("\n\n\t ====== the initial weighted adjoining table is as follows:======\n");for(i = 0; i < size; i++)for(j = 0; j < size; j++)   if(adjTable[i][j])          insertAdj(adj, j, i, adjTable[i][j]); // insertAdj the adjoining table overprintAdjTable(adj, size);   capacity = 7;bh = initBinaryHeap(capacity+1);//conducting prim alg to find minimum spanning tree(MST)startVertex = 1; // you should know our index for storing vertex starts from 0prim(adj, size, startVertex, bh);   return 0;
}

2.3)printing results:



最小生成树——Prim(普利姆)算法相关推荐

  1. (王道408考研数据结构)第六章图-第四节1:最小生成树之普利姆算法(思想、代码、演示、答题规范)

    文章目录 一:普利姆(Prim)算法算法思想 二:普利姆(Prim)算法注意点 三:普利姆(Prim)算法代码实现 四:普利姆(Prim)算法代码视频演示 五:普利姆(Prim)算法动画演示 六:普利 ...

  2. 最小生成树(普利姆算法、克鲁斯卡尔算法)

    给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. 求最小生成树的算法 (1) 克鲁斯卡尔算法 图的存贮结构采用边集数组,且权值相等的边在数组中排列次序可以是 ...

  3. 644-最小生成树Prim普里姆算法

    最小生成树Prim普里姆算法理论 最小生成树的应用场景:顶点代表城市的话,比如说修路,架设电线,网络,怎么让这几个城市连起来,而且花费是最小的,成本最低,权值是最小的,但是不允许形成环路. 第一步的U ...

  4. 普利姆算法(prim)求最小生成树(MST)过程详解

    生活中最小生成树的应用十分广泛,比如:要连通n个城市需要n-1条边线路,那么怎么样建设才能使工程造价最小呢?可以把线路的造价看成权值求这几个城市的连通图的最小生成树.求最小造价的过程也就转化成求最小生 ...

  5. 普利姆算法和克鲁斯卡尔算法求解最小生成树

    Q:最小生成树有什么用? A:譬如我要去五个城市旅游,每两个城市之间可能有路也可能没有,路的距离可能一样也可能不一样,随机从一个城市出发,我想要把每个城市走一遍,怎么样走过的路距离最短,比如我想从上海 ...

  6. Prim Algorithm(普利姆算法)

    Prim算法介绍 普里姆算法(Prim's algorithm),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点,且其所有边的权 ...

  7. Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)

    1.Java普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal) 普利姆算法(Prim)与克鲁斯卡尔算法(Kruskal)求**最小生成树(极小连通子图)**的算法 1.1普利姆算法(Prim) ...

  8. 普利姆算法(Prim)

    给大家介绍一下普利姆算法, 普里姆算法(Prim算法),图论中的一种算法,可在加权连通图里搜索最小生成树.意即由此算法搜索到的边子集所构成的树中,不但包括了连通图里的所有顶点(英语:Vertex (g ...

  9. 普利姆算法(prim)---(韩顺平数据结构)笔记

    普利姆算法 本质:求出从某一结点开始到达其他结点距离花费最少的组合 从图中指定顶点出发,寻找它相连的所有结点,比较这些结点的权值大小,然后连接权值最小的那个结点. 然后将寻找这两个结点相连的所有结点, ...

  10. [算法]最小生成树-普利姆算法

    2019独角兽企业重金招聘Python工程师标准>>> 目前正在看<大话数据结构>,其中介绍了普利姆算法,自己对算法理解能力太差,能够手写求出最小生成树,但是写出算法代码 ...

最新文章

  1. ladar:16线激光雷达(雷神)
  2. Web App适配iPhoneX
  3. python批量生成,用python批量生成简单的xml文档
  4. 笔记-中项案例题-2017年上-风险管理
  5. 近似推断包括采样和变分两种方法,前者是通过_____进行近似,后者是通过_______进行近似。
  6. Enterprise search Callstack in runtime
  7. Nexus 3.31.1 maven 私服 仓库配置篇 linux
  8. Gitlab+Docker实现持续集成(CI)与持续部署(CD)
  9. java 图片拼接_Java拼接多张图片,可以连接在一起 | 学步园
  10. 查看linux服务器内存使用情况,不够时创建Swap、手动 cached
  11. 李开复写给大学生的第四封信的一些笔录
  12. 【Prison Break】第二天(3.28)
  13. 10个线程同时执行i++操作1000次,如何保证结果是1w
  14. 基于FPGA的VGA显示,简单的历程和注释(DE2-115)
  15. 计算机测色配色应用,计算机测色及配色.doc
  16. android毕业论文结论,毕业论文经典结束语
  17. HttpMessageNotReadableException: Required request body is missing
  18. 电赛总结(四)——波形发生芯片总结之AD9854
  19. 专访架构师周爱民:谈企业软件架构设计 1
  20. 通过面向对象实现猫狗大战案例

热门文章

  1. Loj #6089. 小 Y 的背包计数问题
  2. P2183 [国家集训队]礼物(扩展卢卡斯)
  3. 牛客网 【每日一题】7月27日题目精讲—乌龟棋
  4. 【每日一题】4月1日题目 Rinne Loves Edges
  5. 线段树动态开点 - - - > 线段树合并
  6. [2021-09-11 CQBZ/HSZX多校联考 T1] 茅山道术 (后缀和优化dp)
  7. CodeForces:643(VK cup)
  8. LOJ:相框(欧拉回路、分类讨论)
  9. Loj#2769-「ROI 2017 Day 1」前往大都会【最短路树,斜率优化】
  10. CF755G-PolandBall and Many Other Balls【倍增FFT】