1. 程式人生 > >筆記:克魯斯卡爾演算法

筆記:克魯斯卡爾演算法

//用到了並查集和堆排序解決最小生成樹,思路就是權值邊排序(堆排序),然後從最小權值邊取起,邊取邊判定是否有迴路(用並查集),有迴路則放棄該邊。思路相對簡單,直接看程式碼。
#define MaxSize 100
typedef struct{
    int a,b;//邊的兩個頂點
    int weight;//邊的權值
}Edge;//邊結構體
int Find(int *parent,int x){
    while(parent[x]>=0) x=parent[x];//並查集知識點:迴圈向上尋找下標為x頂點的根
    return x;//返回根的下標
}
Edge edges[MaxEdge];//儲存各條邊
int parent[MaxVex];//並查集知識點:儲存各頂點的父親頂點
Void MiniSpanTree_Kruskai(MGraph G){
    int i,n,m;
    sort(edges);//這裡的排序是經過重寫的,按權值由小到大排序
    for(i=0;i<G.vexnum;i++) parent[i]=-1;//初始化,各個頂點單獨形成一個集合
    for(i=0;i<G.arcnum;i++){//遍歷每一條邊
        n=Find(parent.edges[i].a);
        n=Find(parent.edges[i].b);
        if(n!=m){//根節點不同,則不會構成環
            parent[n]=m;
            print("(%d->%d)",edges[i].a,edges[i].b);//訪問
        }    
    }
}

庫魯斯卡爾演算法看起來簡單,但用到了排序sort,因而時間耗費上取決邊的多少,適合稀疏圖。