1. 程式人生 > >Kruskal演算法(一)之 C語言詳解

Kruskal演算法(一)之 C語言詳解

/*
 * 克魯斯卡爾(Kruskal)最小生成樹
 */
void kruskal(Graph G)
{
    int i,m,n,p1,p2;
    int length;
    int index = 0;          // rets陣列的索引
    int vends[MAX]={0};     // 用於儲存"已有最小生成樹"中每個頂點在該最小樹中的終點。
    EData rets[MAX];        // 結果陣列,儲存kruskal最小生成樹的邊
    EData *edges;           // 圖對應的所有邊

    // 獲取"圖中所有的邊"
    edges = get_edges(G);
    // 將邊按照"權"的大小進行排序(從小到大)
    sorted_edges(edges, G.edgnum);

    for (i=0; i<G.edgnum; i++)
    {
        p1 = get_position(G, edges[i].start);   // 獲取第i條邊的"起點"的序號
        p2 = get_position(G, edges[i].end);     // 獲取第i條邊的"終點"的序號

        m = get_end(vends, p1);                 // 獲取p1在"已有的最小生成樹"中的終點
        n = get_end(vends, p2);                 // 獲取p2在"已有的最小生成樹"中的終點
        // 如果m!=n,意味著"邊i"與"已經新增到最小生成樹中的頂點"沒有形成環路
        if (m != n)
        {
            vends[m] = n;                       // 設定m在"已有的最小生成樹"中的終點為n
            rets[index++] = edges[i];           // 儲存結果
        }
    }
    free(edges);

    // 統計並列印"kruskal最小生成樹"的資訊
    length = 0;
    for (i = 0; i < index; i++)
        length += rets[i].weight;
    printf("Kruskal=%d: ", length);
    for (i = 0; i < index; i++)
        printf("(%c,%c) ", rets[i].start, rets[i].end);
    printf("\n");
}