一步一步写算法(之克鲁斯卡尔算法 中)
生活随笔
收集整理的這篇文章主要介紹了
一步一步写算法(之克鲁斯卡尔算法 中)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
一步一步寫算法(之克魯斯卡爾算法 中) 原文:一步一步寫算法(之克魯斯卡爾算法 中)
文章總結:
【 聲明:版權所有,歡迎轉載,請勿用于商業用途。 ?聯系信箱: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)解決了這三個問題,下一篇博客就可以進行歸總分析處理,邏輯上也十分清晰了
【未完,待續】
轉載于:https://www.cnblogs.com/lonelyxmas/p/4157016.html
總結
以上是生活随笔為你收集整理的一步一步写算法(之克鲁斯卡尔算法 中)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: uCOS-II任务的挂起和恢复
- 下一篇: Android Studio升级后报 m