最小生成樹:數組
n個頂點,用n-1條邊把一個連通圖鏈接起來,而且使得權值和最小。ide
- /*
- *1.初始化兩個數組,一個用於存放邊權值,一個用來存放邊權值的起始點
- *2.賦初值,從0開始,全部邊權值都是和v0相關,全部邊權值的起始點都是v0
- *3.大循環1到MG.numVertexes-1次
- *4.遍歷邊權值數組,找當前數組中的最小值,並將終點保存在k中
- *5.打印邊
- *6.將加入的頂點的lowcost設置爲0
- *7.使用新加入的頂點的鄰接矩陣來更新lowcost數組和adjvex數組
- *
- *
- */
- void MiniSpanTree_Prim(MGraph MG){
- int min,i,j,k;
- int adjvex[MAXVEX];//存儲與邊對應的相關起始頂點
- int lowcost[MAXVEX];//存儲頂點間邊的權值
- lowcost[0] = 0;//權值爲0表示此小標(V0)的頂點已經加入到了生成樹中
- adjvex[0] = 0; //初始化第一個頂點的下標爲0
- for(i=1;i<MG.numVertexes;i++){
- lowcost[i] = MG.arc[0][i];//將v0頂點相關的邊的權值存儲數組中
- adjvex[i] = 0;//這些邊的起點都是v0,因此下標都是0
- }
- for(i=1;i<MG.numVertexes;i++){
- min = INFINITY;//最小權值初始化爲無窮,一般將infinity設置爲不可能的大數字
- j=1;k=0;
- while(j<MG.numVertexes){//在lowcost數組中尋找最小值,並記下最小值的終點存儲在k中
- if(lowcost[j]!=0 && lowcost[j]<min){
- min = lowcost[j];
- k = j;
- }
- j++;
- }
- printf("(%d,%d)",adjvex[k],k);//打印邊,起點和終點
- lowcost[k] = 0;//將當前頂點的權值設置爲0,表示此頂點已經完成任務了
- for(j=1;j<MG.numVertexes;j++){//更新lowcost數組,使用剛添加進最小生成樹的那個結點的行!
- if(lowcost[j]!=0 && MG.arc[k][j]<lowcost[j]){//若是下標爲k的頂點各個邊權值小於lowcost的邊權值
- lowcost[j] = G.arc[k][j];//更新lowcost數組
- adjvex[j] = k;//更新與邊權值相關聯的邊起點信息
- }
- }
- }
- }
- /*
- *1.定義一個邊集,一個結點集,將結點集所有初始化爲0,邊集按照權的大小排列
- *2.循環邊集中的每一條邊,檢查每條邊的起點和終點,若是相同就繼續循環,不然打印並修改parent
- *3.定義一個方法Find來尋找結點的走向
- *
- *
- *
- */
- typedef struct{
- int begin;
- int end;
- int weight;
- }Edge;
- void MiniSpanTree_Kruskal(MGraph MG,Edge edges[]){//此處使用元素類型爲Edge的邊集數組,已經按照權值由小到大排列
- int i,n,m;
- int parent[MAXVEX];//定義一數組用來判斷邊與邊是否造成迴路
- for(i=0;i<MG.numVertexes;i++){//初始化數組爲0
- parent[i] = 0;
- }
- for(i=0;i<MG.numEdges;i++){//循環每一條邊
- n = Find(parent,edges[i].begin);//
- m = Find(parent,edges[i].end);//
- if(n != m){//若是m、n不等說明此邊沒有與現有的生成樹造成環路
- parent[n] = m;//數組下標記錄了邊起點,數組值記錄了邊終點
- printf("(%d,%d)%d",edges[i].begin,edges[i].end,edges[i].weight);
- }
- }
- }
- int Find(int *parent,int f){//查找從f這個座標開始能走到的最遠的結點是哪裏
- while(parent[f]>0){//若是最後走到的最遠的結點相同,說明是又環路生成的
- f = parent[f];
- }
- return f;
- }