最小生成树算法

来源:互联网 发布:广告公司开单软件 编辑:程序博客网 时间:2024/05/16 10:14

最小生成树算法:

kruskal算法(克鲁斯卡尔算法)--贪婪算法

求加权连通图的最小生成树的算法。kruskal算法总共选择n- 1条边,(共n个点)所使用的贪婪准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。kruskal算法分e 步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。


算法简单描述:

1).记Graph中有v个顶点,e个边
2).新建图Graphnew,Graphnew中拥有原图中相同的e个顶点,但没有边
3).将原图Graph中所有e个边按权值从小到大排序
4).循环:从权值最小的边开始遍历每条边 直至图Graph中所有的节点都在同一个连通分量中
                if 这条边连接的两个节点于图Graphnew中不在同一个连通分量中
                           添加这条边到图Graphnew中

代码实现:

typedef struct          {            char vertex[VertexNum];                                //顶点表             int edges[VertexNum][VertexNum];                       //邻接矩阵,可看做边表             int n,e;                                               //图中当前的顶点数和边数         }MGraph;  typedef struct node  {      int u;                                                 //边的起始顶点       int v;                                                 //边的终止顶点       int w;                                                 //边的权值   }Edge; void kruskal(MGraph G)  {      int i,j,u1,v1,sn1,sn2,k;      int vset[VertexNum];                                    //辅助数组,判定两个顶点是否连通       int E[EdgeNum];                                         //存放所有的边       k=0;                                                    //E数组的下标从0开始       for (i=0;i<G.n;i++)      {          for (j=0;j<G.n;j++)          {              if (G.edges[i][j]!=0 && G.edges[i][j]!=INF)              {                  E[k].u=i;                  E[k].v=j;                  E[k].w=G.edges[i][j];                  k++;              }          }      }         heapsort(E,k,sizeof(E[0]));                            //堆排序,按权值从小到大排列           for (i=0;i<G.n;i++)                                    //初始化辅助数组       {          vset[i]=i;      }      k=1;                                                   //生成的边数,最后要刚好为总边数       j=0;                                                   //E中的下标       while (k<G.n)      {           sn1=vset[E[j].u];          sn2=vset[E[j].v];                                  //得到两顶点属于的集合编号           if (sn1!=sn2)                                      //不在同一集合编号内的话,把边加入最小生成树           {            printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w);                   k++;              for (i=0;i<G.n;i++)              {                  if (vset[i]==sn2)                  {                      vset[i]=sn1;                  }              }                     }          j++;      }  }



0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 一周七个月宝宝消化不良拉屎怎么办 孩子总是消化不良拉屎不成型怎么办 一岁宝宝长牙慢怎么办 一岁宝宝不喝水怎么办 七个月的宝宝咳嗽怎么办 怀孕七个月感冒了怎么办 苹果汁弄到白色衣服怎么办 宝宝大便干燥拉不出来怎么办 婴儿吃过青菜米粉呕吐怎么办 50天宝宝便秘5天怎么办 8个月婴幼儿便秘怎么办 1个月婴幼儿便秘怎么办 榨汁后的苹果渣怎么办 宝宝6个月后容易生病怎么办 婴儿头型睡偏了怎么办 6个月婴儿不吃奶怎么办 宝宝秋季腹泻反复发烧怎么办 纯甄过期一个月怎么办 四个月宝宝不吃奶瓶怎么办 四个月宝宝不吃奶粉怎么办 婴儿三四天不大便怎么办 婴儿几天不拉大便怎么办 新生儿6天不拉屎怎么办 孩子10天不大便怎么办 宝宝5天没拉屎怎么办 小孩4-5天不大便怎么办 三个月宝宝睡前哭闹厉害怎么办 新生儿抱着睡放下就醒怎么办 宝宝大运动发育迟缓怎么办 八个月宝宝不会爬怎么办 宝宝竖着抱早了怎么办 孕妇吃的水果少怎么办 6个月宝宝厌奶怎么办 5个月宝宝厌奶怎么办 11个月宝宝厌奶怎么办 母乳宝宝不喝奶粉怎么办 换奶粉不拉大便怎么办 宝宝和妈妈不亲怎么办 冬天榨果汁太凉怎么办 四个月宝宝拉水怎么办 婴儿吃奶吃撑了怎么办