一步一步写算法(之克鲁斯卡尔算法 中)
原文:一步一步写算法(之克鲁斯卡尔算法 中)

【 声明:版权所有,欢迎转载,请勿用于商业用途。  联系信箱:feixiaoxing @163.com】

前面说到,克鲁斯卡尔的算法是按照各个line的权重依次进行添加的,那么这就涉及到一个权重的排序问题。怎么排序呢?可以采用最简单的冒泡排序算法。可是这里排序的是数据结构,怎么办呢?那就只好采用通用排序算法了。

void bubble_sort(void* array[], int length, int (*compare)(void*, void*), void(*swap)(void**, void**))
{int outer;int inner;for(outer = length -1; outer >0; outer --){for(inner = 0; inner < outer; inner ++){if(compare(array[inner], array[inner + 1]))swap(&array[inner], &array[inner + 1]);}}return;
}

所以,这里就要添加上属于DIR_LINE的compare和swap函数,

int compare(void* data1, void* data2)
{DIR_LINE* line1 = (DIR_LINE*) data1;DIR_LINE* line2 = (DIR_LINE*) data2;return (line1->weight > line2->weight) ? 1 : 0;
}void swap(void** data1, void** data2)
{DIR_LINE* median;DIR_LINE** line1;DIR_LINE** line2;line1 = (DIR_LINE**) data1;line2 = (DIR_LINE**) data2;median = *line1;*line1 = *line2;*line2 = median;
}

排序结束之后,我们就开始线段的插入工作,那么进行线段插入的时候,我们需要知道当前线段是不是在某一个最小生成树中已经存在了,如果是这样的话,那么这个线段就要被忽略了。所以,这中间还存在一个判断的问题,

int getVectexNumFromTree(MINI_GENERATE_TREE* pTree, int start, int end)
{int index;int total;total = 0;for(index = 0; index < pTree->node_num; index++){if(start == pTree->pNode[index]){total ++;continue;}if(end == pTree->pNode[index]){total ++;}}return total;
}int isDoubleVectexExistInTree(MINI_GENERATE_TREE* pTree[], int length, int start, int end)
{int index = 0;int value = 0;int number = 0;for(index = 0; index < length; index ++){number = getVectexNumFromTree(pTree[index], start, end);if(number > value)value = number;}return (value == 2) ? 1 : 0;
}

线段的判断之后,如果发现在两颗独立的最小生成树上面,那么还需要进行合并操作,删除其中一个最小生成树,把另外一个生成树的所有点和线段都要添加到没有删除的这颗最小生成树上面。当然还有一点不要忘记了,最后还要加上端口分别在两棵树上的这个线段。

void  mergeTwoMiniGenerateTree(MINI_GENERATE_TREE* pTree[], int length, int start, int end, int weight)
{MINI_GENERATE_TREE* pFirst;MINI_GENERATE_TREE* pSec;DIR_LINE* line;int index;/* 删除多余的最小生成树 */pFirst = find_tree_by_index(pTree, length, start);pSec = find_tree_by_index(pTree, length, end);delete_mini_tree_from_group(pTree, length, pSec);/* 合并节点 */for(index = 0; index < pSec->node_num; index ++){pFirst->pNode[pFirst->node_num + index] = pSec->pNode[index];}pFirst->node_num += pSec->node_num;/* 合并线段 */for(line = pSec->pLine; line; line = line->next){insert_line_into_queue(&pFirst->pLine, line->start, line->end, line->weight);}insert_line_into_queue(&pFirst->pLine, start, end, weight);/* 函数返回 */return;
}

文章总结:

(1)本篇主要介绍了克鲁斯卡尔算法编写中需要处理的三个问题,排序、查找和合并

(2)复杂的函数都是由简单的函数构造而成的,我们可以把算法分成几个独立的部分,各个击破

(3)解决了这三个问题,下一篇博客就可以进行归总分析处理,逻辑上也十分清晰了

【未完,待续】

posted on 2014-12-11 10:24 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/4157016.html

一步一步写算法(之克鲁斯卡尔算法 中)相关推荐

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

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

  2. 用c语言描述普里姆算法和克鲁斯卡尔算法,克鲁斯卡尔算法+普里姆算法 详解

    克鲁斯卡尔算法: [1]克鲁斯卡尔算法 普里姆算法是以某顶点为起点,逐步找各顶点上最小权值的边来构建最小生成树. 克鲁斯卡尔算法是直接以边为目标去构建. 因为权值是在边上,直接去找最小权值的边来构建生 ...

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

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

  4. 十大常用算法之克鲁斯卡尔算法

    十大常用算法的完整实现 一.二分查找算法:https://blog.csdn.net/weixin_46635575/article/details/121532149 二.分治算法:https:// ...

  5. 贪心算法之克鲁斯卡尔算法

    最小生成树性质:设G=(V,E)是一个连通网络,U是顶点集V的一个真子集.若(u,v)是G中一条"一个端点在U中(例如:u∈U),另一个端点不在U中的边(例如:v∈V-U),且(u,v)具有 ...

  6. 【数据结构】图的应用(普利姆算法、克鲁斯卡尔算法、迪杰斯特拉算法、弗洛伊德算法、拓扑排序)

    最小生成树 什么是最小生成树 是一棵树 - 无回路 - |V|个顶点一定有|V|-1条边 是生成树 - 包含全部顶点 - |V|-1条边全在图里 贪心算法 什么是"贪":每一步都要 ...

  7. 最小生成树——普里姆算法和克鲁斯卡尔算法

    最小生成树 用来解决工程中的代价问题. 一:普里姆算法 具体代码用C语言实现如下: typedef int VRType;typedef char InfoType;#define MAX_NAME ...

  8. 【算法】克鲁斯卡尔算法

    1.概述 视频地址:克鲁斯卡尔算法 下面看一个场景和问题 某城市新增7个站 点(A,B,C,D,E,F,G),现在需要修路把7个站点连通 各个站点的距离用边线表示(权),比如A-B距离12公里 问:如 ...

  9. 两种构造最小生成树的算法(普里姆算法,克鲁斯卡尔算法)

    (一)普里姆算法 普里姆算法求最小生成树:从生成树中只有一个顶点开始,到定点全部进入生成数为止: 2.克鲁斯卡尔算法. 思想:将所有边按其权值从小到大排一遍,从小到大依次选取边,加入最小生成树中,若加 ...

  10. 十大算法之克鲁斯卡尔算法

    克鲁斯卡尔算法介绍 克鲁斯卡尔(Kruskal)算法,是用来求加权连通图的最小生成树的算法. 基本思想:按照权值从小到大的顺序选择n-1条边,并保证这n-1条边不构成回路 具体做法:首先构造一个只含n ...

最新文章

  1. Scrum团队选择scrum看板工具的7点特征
  2. 【Splay】洛谷3372 【模板】线段树 1
  3. Java ACM模式
  4. 利用lrz、lsz工具在linux与windows之间传输文件
  5. tftp服务器连接开发板下载内核提示:retry count exceeded; starting again
  6. 2 android学习资料
  7. robot:循环遍历数据库查询结果是否满足要求
  8. 【分享】 codeReview 的重要性
  9. SQL Server 2019中SQL表变量延迟编译
  10. 手机qq怎么添加相册表情包_手机qq怎么制作表情包配文字
  11. python pandas 数据透视表_python 用pandas实现数据透视表功能
  12. vue中使用AntV G6 — 基础篇
  13. java图片降噪_Java基于opencv实现图像数字识别(四)—图像降噪
  14. rimraf : 无法加载文件,‘set-executionpolicy‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。
  15. 使用Pyppeteer进行gmail模拟登录
  16. cocos2d-x项目101次相遇:使用触摸事件移动 精灵
  17. java实现十进制数转换成二进制数
  18. 【Developer Log】ProGuard扰码web项目(WAR)
  19. 串口编程 - ascii字符与16进制的相互转换
  20. 解密阿里巴巴加密技术: 爬虫JS逆向实践-1688 【JS混淆加密解析】

热门文章

  1. mc服务器音乐文件夹在哪,添加自定义音乐图文教程 我的世界怎么添加音乐
  2. 【quartz】执行一次功能
  3. tensorflow-gpu2.x无法检测到GPU设备
  4. php unable to save,php – Laravel save()未定义
  5. 切换 uniapp_万能前端框架uni app初探03:底部导航开发
  6. elasticsearch dump 教程
  7. 普通爬虫有啥意思,我写了个通用Scrapy爬虫
  8. 又跌!6月全国程序员工资新统计,太扎心
  9. 刷新纪录 | 74.7 秒训练完 ImageNet!2048 GPU 暴力出奇迹
  10. 你还在用Python做数据分析么?