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
- 16 - 12 - 06 克鲁斯卡尔(Kruskal)算法详解
- 克鲁斯卡尔(Kruskal)算法
- 克鲁斯卡尔(Kruskal)算法
- kruskal克鲁斯卡尔算法
- 克鲁斯卡尔算法(Kruskal)
- 克鲁斯卡尔算法(Kruskal)模板
- 克鲁斯卡尔(Kruskal)算法
- (Kruskal)克鲁斯卡尔算法
- kruskal's algorithm.[克鲁斯卡尔算法]
- [数据结构]克鲁斯卡尔(Kruskal)算法
- Kruskal(克鲁斯卡尔)
- 克鲁斯卡尔Kruskal
- 最小生成树之克鲁斯卡尔(Kruskal)算法实现,代码详解!!!!
- Kruskal(克鲁斯卡尔) 最小生成树 算法详解+模板
- 普利姆(prim)算法和克鲁斯卡尔(kruskal)算法
- 普里姆算法(Prim)和克鲁斯卡尔(Kruskal)算法
- Prim(普利姆)算法+Kruskal(克鲁斯卡尔)算法
- 普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法
- Java中使用Jedis操作Redis
- 关于mybatis只能查询英文,不能查询中文的问题
- SpringMVC 过滤器Filter使用解析
- 网络爬虫
- Android 内存泄漏(一)
- 16 - 12 - 06 克鲁斯卡尔(Kruskal)算法详解
- c#可空类型(Nullable)
- windows核心编程-WaitForMultipleObjects
- 滤波器的主要特性指标
- 两个数互换
- oracle 12c 无法使用 os 认证登录数据库 ERROR: ORA-01017: invalid username/password; logon denied
- springMVC读取application.properties内容
- MFC学习笔记(2)——Windows程序的类封装 上
- 从请求中获取xml内容并解析成map