16 - 12 - 06 克鲁斯卡尔(Kruskal)算法详解

来源:互联网 发布:清雅源茗茶淘宝买吗 编辑:程序博客网 时间:2024/05/21 23:00

算法思路:
直接以边为目标去构建,直接去找最小权值的来构建生成树也是很自然的想法。
只需在构建时小心不要形成环路即可。自然地用到了边集数组。

运行结果↓:
这里写图片描述

<<<想看代码吗 ? 在最下面 >>>

//////精华分析:之 一步一步分析代码: 污深深带你浪哟带你飞////////

因为一条边由两个顶点组成,我们把一条边的前后两个顶点按大小排好,填入edges方格列表,暂且 一个叫前点,一个叫后点
定义的parent 数组 类比 普里姆中的 adjvex 与 lowcost 数组。
比如parent[2] = 5,并不单纯,
既然加入了parent[ ]数组,说明你已经 被 生成树 接收了,但是克鲁斯卡尔 生成树要的是边啊,咋办呢??
看代码:
if(n!=m)
parent[n]=m;
他的意思是 : parent[2] = 5 表示 (2,5)这条边入生成树。
一箭双雕,一石二鸟,一枪两妾真是厉害了,心机BOY。。。

回到Find() 函数
讲解:while ( parent[f] ! = 1 )
{
–因为edges方格列表是按大小次序来排的,所以检验时即可以优先检验 begin 域 (毕竟我们人为的按由小到大 对begin域和end域进行了排列),
倘若 parent[f] 不等于 -1 ;说明 以 2 为前点某个边已经入生成树了,这时候我们要特别小心,以免他们互相勾搭生成环。所以就有了后面的检验:
f = parent [ f ] ;
将parent[ f ] (后点) 重新赋给 f ,要是while 还能循环,说明这几个点都是有线连着的,这就太危险啦!!
比如:前几次 loop Find函数的while 循环没执行,说明几个入树的节点并不相连。loop 1~~loop4 入树的是:(0,2);(3,5);(1,4);(2,5)。但是后来到 loop 5(循环 5 )的时候,发生了一些节点相连接的事情。
loop 5 时,(0,3) 想入树,但大家看出它好像跟 (0,2);(3,5) 都有一腿,
动用审查代码:f = parent [ f ] ; 直到parent[5] == -1
说明并不是死循环啊,说明好像不成环,这才罢休。

而后是终极审查!!! 。(下面有句话说错了,应该是要是万一几个节点相连)

看上图 if(n != m)
说明从不同的出口出来,也就最终说明不会构成回路,
但若是n = m 你们丫都穿一条裤子了,这构成环路乱搞的事情算是板上钉钉了。

来人啊!乱棍打出生成树学习小组!!!
就这么,(0,3)再也没有了进入生成树的机会。。。。。。
( 其他的以此类推即可 )

<<<——–下面是代码君———>>>

#include <stdio.h>  #include <stdlib.h>  #define MAXEDGE 10  #define MAXVEX 6  /*定义边集数组*/struct Edge{      int begin;      int end;      int weight;  };  struct MGraph{      int numVertexes;      int numEdges;      int *vex;      Edge *edges;  };  int Find(int *parent,int f)  {  /*结点f与parent[f]是否连接(或者间接即多跳连接)着(在边子集中)同一个结点*/        while(parent[f]!=-1) /*循环!loop!*/         f=parent[f];      return f;  }  int IsCompleted(int *parent)  {      int i;      int n=0;      for(i=0;i<MAXVEX;++i)      {          if(parent[i]!=-1)              ++n;      }      if(n==MAXVEX-1)  //最小生成树的特点是n各节点有n-1条边          return 1;      else          return 0;  }  void MiniSpanTree_Kruskal(MGraph *G)  {      int i,n,m;      //Edge edges[MAXEDGE];  //边集数组      int parent[MAXVEX];      for(i=0;i<G->numVertexes;++i)          parent[i]=-1;       for(i=0;i<G->numEdges;++i)      {          n=Find(parent,G->edges[i].begin);          m=Find(parent,G->edges[i].end);        /*判断结点edges[i].begin与edges[i].end是否连接(或者间接即多跳连接)着(在边子集中)同一个结点*/        /*注意:假设结点edges[i].begin与结点edges[i].end都跟量外一个结点X相连(或者间接相连),如若不加判断,则三个结点会形成回路*/           /*if(n!=m && parent[n]!=m)*/          if(n!=m)          {              parent[n]=m;              printf("(%d,%d)  %d\n",G->edges[i].begin,G->edges[i].end,G->edges[i].weight);          }          //怎么判断生成树已连通原图,即已生成生成树          if(IsCompleted(parent))              return;      }  }  int main()    {        MGraph *my_g = (struct MGraph*)malloc(sizeof(struct MGraph));        int i,j;        int t = 0;        my_g->numVertexes = 6;      my_g->numEdges = 10;      my_g->vex = (int*)malloc(sizeof(char)*my_g->numVertexes);        if(!my_g->vex)         return -1;   //原式是return;     for(i = 0 ; i < my_g->numVertexes ; ++i)           //一维数组(图中各结点编号)初始化{0,1,2,3,4,5}            my_g->vex[i] = i ;        my_g->edges = (Edge*)malloc(sizeof(Edge)*MAXEDGE);      if(!my_g->edges)          return -1;  //原式是return;      //简单起见,边集数组(按边的权值从小到大排序)直接输入      my_g->edges[0].begin=0; my_g->edges[0].end=2; my_g->edges[0].weight=1;      my_g->edges[1].begin=3; my_g->edges[1].end=5; my_g->edges[1].weight=2;      my_g->edges[2].begin=1; my_g->edges[2].end=4; my_g->edges[2].weight=3;      my_g->edges[3].begin=2; my_g->edges[3].end=5; my_g->edges[3].weight=4;      my_g->edges[4].begin=0; my_g->edges[4].end=3; my_g->edges[4].weight=5;      my_g->edges[5].begin=1; my_g->edges[5].end=2; my_g->edges[5].weight=5;      my_g->edges[6].begin=2; my_g->edges[6].end=4; my_g->edges[6].weight=5;      my_g->edges[7].begin=0; my_g->edges[7].end=1; my_g->edges[7].weight=6;      my_g->edges[8].begin=4; my_g->edges[8].end=5; my_g->edges[8].weight=6;      my_g->edges[9].begin=2; my_g->edges[9].end=3; my_g->edges[9].weight=7;      MiniSpanTree_Kruskal(my_g);    }    

——————————-全剧终—————————————-

这篇博客写的蛮爽的。。

来啊!点赞啊!
来啊!关注啊~~

————————取材《大话数据结构》
—————————–《鱼c –数据结构与算法》
—-coding感谢: htp://blog.csdn.net/ppalive_/articledetails/47761015

3 0
原创粉丝点击