一步一步写算法(之克鲁斯卡尔算法 中)
来源:互联网 发布:网络时间校准器 编辑:程序博客网 时间:2024/05/04 20:15
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱: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)解决了这三个问题,下一篇博客就可以进行归总分析处理,逻辑上也十分清晰了
【未完,待续】
- 一步一步写算法(之克鲁斯卡尔算法 中)
- 一步一步写算法(之克鲁斯卡尔算法 中)
- 一步一步写算法(之克鲁斯卡尔算法 上)
- 一步一步写算法(之克鲁斯卡尔算法 下)
- 一步一步写算法(之克鲁斯卡尔算法 上)
- 一步一步写算法(之克鲁斯卡尔算法 下)
- 贪心算法之克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 克鲁斯卡尔算法
- 图 结构
- 关于WM_ERASEBKGND和WM_PAINT的深刻理解
- [转]关于unicode,mbcs,utf8,charset,encoding等相关概念的说明
- xfire客户端
- C语言中的宏定义
- 一步一步写算法(之克鲁斯卡尔算法 中)
- 黑马程序员 关闭和释放连接 Close方法与Dispose方法
- 入侵已没有意义
- 图的基本结构
- 怀念那段黑客
- QQ空间挂马
- mapinfo操作(转载http://www.cnblogs.com/glacierh/archive/2008/08/07/1263044.html)
- 冰点过期破解
- 解决Fedora 16字体发虚问题