圖的廣度遍歷、深度遍歷及最小生成樹書演算法(Prim、Kruskal)
阿新 • • 發佈:2019-01-08
typedef struct { char vertex[VertexNum]; //頂點表 int edges[VertexNum][VertexNum]; //鄰接矩陣,可看做邊表 int n,e; //圖中當前的頂點數和邊數 }MGraph; typedef struct node { int u; //邊的起始頂點 int v; //邊的終止頂點 int w; //邊的權值 }Edge; void kruskal(MGraph G) { int i,j,u1,v1,sn1,sn2,k,w; int vset[VertexNum]; int vsetE[VertexNum][VertexNum]; //輔助陣列,判定兩個頂點是否連通 int E[EdgeNum]; //存放所有的邊 k=0; //E陣列的下標從0開始 for (i=0;i<G.n;i++) { for (j=0;j<G.n;j++) { if (G.edges[i][j]!=0 && G.edges[i][j]!=INF) { E[k].u=i; E[k].v=j; E[k].w=G.edges[i][j]; k++; } } } heapsort(E,k,sizeof(E[0])); //堆排序,按權值從小到大排列 for (i=0;i<G.n;i++) //初始化輔助陣列 { vset[i]=i; } k=1; //生成的邊數,最後要剛好為總邊數 j=0; w=0; //E中的下標 while (k<G.n) { sn1=E[j].u; sn2=E[j].v; //得到兩頂點屬於的集合編號 if (sn1!=sn2) //不在同一集合編號內的話,把邊加入最小生成樹 { printf("%d ---> %d, %d",E[j].u,E[j].v,E[j].w); k++; if(has(vest,sn1)&&has(vest,sn1)) { continue; } else if(!has(vest,sn1)&&has(vest,sn1)) { vest[w++] = sn1; vestE[sn1][sn2] = vestE[sn2][sn1] = E[j].w; } else if(has(vest,sn1)&&!has(vest,sn1)) { vest[w++] = sn2; vestE[sn1][sn2] = vestE[sn2][sn1] = E[j].w; } else { vest[w++] = sn1; vest[w++] = sn2; vestE[sn1][sn2] = vestE[sn2][sn1] = E[j].w; } } j++; } printf() } bool has(int a[],int n){...} //a[]中含有n返回ture,否則返回false