(原创)最小生成树之Prim(普里姆)算法+代码详解,最懂你的讲解

代码显示有问题,可移步博客园:https://www.cnblogs.com/yx1999/p/10357626.html

Prim算法


(哈欠)在创建最小生成树之前,让我们回忆一下什么是最小生成树。最小生成树即在一个待权值的图(即网结构)中用一个七拐八绕的折线串连起所有的点,最小嘛,顾名思义,要权值相加起来最小,你当然可以拿起笔来就算你脑中的每一种可能,但是如果你了解了这种算法,你就能跟我一样,一次画出完美答案。

上个栗子:

我先说一哈这个算法的方法论,然后我们来代码实现一下,在讲解开始之前,敲黑板,记得我们要生成一个权值最小的树,所以每一步都要考虑到树的每一个结点,不要孤立地用一个结点来对比从而走上死路,我们任选一个点开始生成,教材里选的 v0,那我们就选 v8,战斗开始

v8 有三条路,分别通往v1 v2 v3,v2那条路权值最小,ok, v2→v8,然后我们该看什么,如果你说找和 v2 相邻的 v8 以外的边,那我刚才的强调就gg了,我们找v2 和 v8除相连的线之外的所有分支,易得 v8→v1的权值最小,ok,下一步找哪几个点?v2 v1 v8这三个点除两条连接线以外的所有分支,挑最小的那一条,后面重复前面的操作,每次都把新加入的伙伴算在找线之内才对,自己画一下给答案:



操作一遍是不是发现还真的跟哪个点开始没鸡儿关系,因为每个点都要连到,关键就在于沿最小分支找点的时候一定要把它看成一个树结构来找,才算是最小生成树。

还是给一下标准定义:


我们把构造连通网的最小代价(权值)生成树 称为最小生成树 (Minimum Cost Spanning Tree)。

方法论就到这里,相信下一次看到同样的现实问题,你也应该能在第一时间用正确的思路找到合适的路。

在代码实现之前,我们先请来连通图的好基友——邻接矩阵

我们发现一行一行的矩阵很容易显示权值,这样就可以快速对比权值的大小,只要在循环的每一步留存下权值较小的边权值和顶点下标,就可以实现。

和以前一样,我们还是用 INFINITY 来表示无限大,即不存在该边

代码如下:

 void MiniSpanTree_Prim(MGragh G)

 {

    int mini,i,j,k;

    int adjvex[MAXVEX]; //保存相关顶点下标

     int lowcost[MAXVEX]; //保存相关顶点间边的权值

    lowcost[0] = 0;//这里把第0位的权值置0表示v0已加入生成树

    //ps:lowcost[i] = 0 表示i那个下标的顶点加入生成树

    adjvex[0] = 0; //初始化第一个顶点的下标为0

    for(i = 0; i < G.numVertexes; i++)

    {

        lowcost[i] = G.arc[0][i];//将vo相关顶点的权值存入lowcost数组

        adjvex[i] = 0;//置所有下标为v0

    }

    for(i = 1; i < G.numVertexes; i++) //最小生成树开始辽

    {

        mini = INFITINY; //先把权值的最小值置为无限大

        j = 1;

        k = 0;

        while(j < G.numVertexes)

        {

            if(lowcost[j] != 0 && lowcost[j] < mini)//判断并向lowcost中添加权值

            {

                mini = lowcost[j];

                k = j;

            }

            j++;

        }

        printf("(%d %d)",lowcost[k],k);

        lowcost[k] = 0;//置0表示这个定点已经完成任务,找到最小权值分支

        for(j = 1; j < G.numVertexes; j++)

        {

            if(lowcost[j] != 0 && G.arc[k][j] < lowcost[j])

            {

                lowcost[j] = G.arc[k][j];

                adjvex[j] = k;

            }

        }

    }

}

简单讲解一哈:

4~5行,先说 adjvex[] ,这个数组要解决的问题就是存入已经安排好的那些顶点的下标,什么叫安排好了呢,比如我已经找到了 v0→v1 ,v1 就可以算是安排好了,而v0点置0则算做初始化的操作;再说 lowcost[] 这个数组,听名字就是最小权值的意思,下面讲循环的时候详解这个东西到底储存了些什么,然后每次更新之后能做什么

6~13行完全是初始化,要注意的是就是 lowcost[] 储存了邻接矩阵 v0 这一行的权值

14~38行是最小生成树的整体代码

16行就是每次都把最小值重置

19~27行,从 1 开始遍历完全,找到现在这个状态下的最小权值数,并且把这个下标用 k 存住,28行就是把权值和下标打印出来,当然也可以换成别的操作,这里不再赘述

 然后29行,看看他都干了些什么,它把  adjvex[ k ] 置0,看一下第一点,这里表示 v1 完成任务,没有利用价值了

然后30~37这个循环,看看循环的条件,条件一:  lowcost[ j ] != 0,这是啥意思,表示在没有完成任务的顶点中选择,条件二: G.arc[k][j] < lowcost[j]   这表示在刚才找到的新顶点的矩阵那一行去对应,如果有更小的权值就把 lowcost[] 更新掉,这样就保证了这个数组中同时存在好几个顶点的权值信息,还是择优录用的,然后返回循环头,再找这次的最小权值点,周而复始。

时间复杂度 O(n²) ,没啥问题辽

最后附上过程图:


谢谢大嘎

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • 图的定义与术语 1、图按照有无方向分为无向图和有向图。无向图由顶点和边构成,有向图由顶点和弧构成。弧有弧尾和弧头之...
    unravelW阅读 402评论 0 0
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,340评论 0 2
  • 1)这本书为什么值得看: Python语言描述,如果学的Python用这本书学数据结构更合适 2016年出版,内容...
    孙怀阔阅读 12,463评论 0 15
  • 不喜欢这样的焦虑,来探讨存在的意义,在自我的世界,开始怀疑自己! 等待的时间总是煎熬,煎熬的过程产生无奈,在无奈叹...
    麦穗姑娘阅读 223评论 0 0
  • 《夏洛特烦恼》这部影片很多人都看过,里面剧情也不陌生。很多人都说因为夏洛不劳而获,不是靠自己奋斗得来的成功,所...
    一枚音符阅读 477评论 0 3