void SetUnion(SetType S[],ElementType X1,ElementType X2) { int Root1,Root2; Root1 = SetFind(S,X1); Root2 = SetFind(S,X2); if(Root1 != Root2){ if(S[Root1].parent < S[Root2].parent ){/*集合1 > 集合2*/ S[Root1].parent += S[Root2].parent; S[Root2].parent = Root1; } else{ S[Root2].parent += S[Root1].parent; S[Root1].parent = Root2; } } }
void KruskalALG(ALGraph * G){ char v; int i,j,k,parent1,parent2,EdgeNum; EdgeNode * edge; SetType S[G->n]; MinHeap H; H = (MinHeap)CreateMinHeap(); int Visited[G->n]; // Initialization for(i=0; i<G->n; i++){ S[i].Data = G->Adjlist[i].Vertex; //将所有的顶点存入生成树的集合 S[i].Parent = -1; //一开始所有顶点都是一棵独立的树 Visited[i] = FALSE; edge = G->Adjlist[i].FirstEdge; while( edge ){ //将所有的边组成一个最小堆(越上面的元素值越小) MinHeapInsert(H,edge); edge = edge->Next; } } EdgeNum = 0; while( EdgeNum < (G->n) || !IsEmptyMin(H) ){ //为什么不是找到n-1条边就停下:因为按目前的写法边数的增加次数和点的输出次数保持一致 //要输出n个点,EdgeNum就必须++ n次【需改进】 edge = (EdgeNode*)DeleteMin(H); parent1 = SetFind(S,G->n,edge->Vertex); parent2 = SetFind(S,G->n,edge->AdjV); if( parent1!=parent2 || parent1==-1 ){ if( !Visited[edge->Vertex] ) { printf("Visited Vertex : %c \n",S[edge->Vertex]); Visited[edge->Vertex] = TRUE; EdgeNum++; } if( !Visited[edge->AdjV] ) { printf("Visited Vertex : %c \n",S[edge->AdjV]); Visited[edge->AdjV] = TRUE; EdgeNum++; } SetUnion(S,G->n,edge->Vertex,edge->AdjV); } } if( EdgeNum < G->n ) printf("图不连通\n"); return ; }
static int SetFind(int set,int label,int dest){ if (set!=EMPTY_SET) { if (setless(label,dest,setnodes[set].label,setnodes[set].dest)) { return SetBuild(SetFind(setnodes[set].parent,label,dest),setnodes[set].label,setnodes[set].dest); } if (seteq(label,dest,setnodes[set].label,setnodes[set].dest)) { return set; } } return SetBuild(set,label,dest); }
SetName SetFind(SetType S[],ElementType X) { int i; for(i=0;i<MAXN;i++){ if(S[i].Data == X) break; } if(S[i].parent < 0) return i; else return S[i].parent = SetFind(S,S[S[i].parent].Data); }
/* Print a set */ PRIVATE void SetPrint(FILE *out, char *set, struct lmno *lmnop) { int i; char *spacer; spacer = ""; fprintf(out,"%12s[",""); for(i=0; i<lmnop->nterminal; i++) { if(SetFind(set,i)) { fprintf(out,"%s%s",spacer,lmnop->symbols[i]->name); spacer = " "; } } fprintf(out,"]\n"); }
int SetInsert(int set,int label,int dest){ int i,hc,s; hc=sethashcode(set,label,dest) & sethashmask; for(i=sethash[hc];i!=EMPTY_LIST;i=setbuckets[i].next){ if (setbuckets[i].set==set&&setbuckets[i].label==label&&setbuckets[i].dest==dest) return setbuckets[i].bigset; } s=SetFind(set,label,dest); if (setnodes[s].parent!=set) { setcheckbucket(); hc=sethashcode(set,label,dest) & sethashmask; setbuckets[setbucketnext].set=set; setbuckets[setbucketnext].label=label; setbuckets[setbucketnext].dest=dest; setbuckets[setbucketnext].bigset=s; setbuckets[setbucketnext].next=sethash[hc]; sethash[hc]=setbucketnext; setbucketnext++; } return s; }