---
# System prepended metadata

title: 最小生成樹演算法(minimum spanning tree)

---

# 最小生成樹演算法(minimum spanning tree) 

## Kruskal`s algorithm MST
```c=
#include <stdio.h> 
#include <stdlib.h> 
struct Edge{
	int src;//source
	int dest;//destination
	int weight;
};

struct Graph{
	int V;//number of vertex
	int E;//number of edge
	
	struct Edge *edge;//graph contain edge
};
struct subset{
	int parent;//root of this vertex 
	int rank;//to compare union order
};
//initialize graph
struct Graph* createGraph(int V,int E){
	//allocate memory
	struct Graph* graph=(struct Graph*)malloc(sizeof(struct Graph));
	//push value
	graph->V=V;
	graph->E=E;
	graph->edge=(struct Edge*)malloc(graph->E*sizeof(struct Edge));//allocate E times to the poiner edge
	
	return graph;
};
int find(struct subset subsets[],int i){//all subset,edge
	if(subsets[i].parent!=i)//root not i itself
		subsets[i].parent=find(subsets,subsets[i].parent);//find until reach
		
	return subsets[i].parent;//if reach the root
}

void Union(struct subset subsets[],int x,int y){
	int xroot=find(subsets,x);
	int yroot=find(subsets,y);
	
	if(subsets[xroot].rank>subsets[yroot].rank){//rank:xroot>yroot
		subsets[yroot].parent=xroot;//change yroot parent
	}
	
	else if(subsets[xroot].rank<subsets[yroot].rank){//rank:xroot<yroot
		subsets[xroot].parent=yroot;//change xroot parent
	}
	else{//rank:xroot=yroot
		subsets[yroot].parent=xroot;//change yroot parent
		subsets[xroot].rank++;//rank up
	}
}
int myComp(const void*a,const void *b){// compare rule
	struct Edge* a1=(struct Edge*)a;//parameter convert
	struct Edge* b1=(struct Edge*)b;
	//must >，that will from small to large 
	return a1->weight > b1->weight;//a1 and b1 is pointer so use -> not .
}
void KruskalMST(struct Graph* graph){
	
	int V=graph->V;//get V graph
	//result edge
	struct Edge result[V];//don't allocate,number of edge will be V
	int e=0;//selected edge order
	int i=0;//tested edge
	//allocate and initial subsets
	struct subset* subsets=(struct subset*)malloc(V*sizeof(struct subset));//number of vertices subset[]
	for(int v=0;v<V;v++){
		subsets[v].parent=v;//itself
		subsets[v].rank=0;//from 0
	}
	//qsort let smallest at front
	qsort(graph->edge,graph->E,sizeof(graph->edge[0]),myComp);//edge in graph,number of edge in graph,size of edge,rule
	
	while(e < (V-1) && i < (graph->E)){//when e is V-1，i must < graph->E
		
		//test if have cylce or not
		//find and Union
		struct Edge next_edge = graph->edge[i];//fixed the edge
		i++;//to next graph of edge
		int x=find(subsets,next_edge.src);//src
		int y=find(subsets,next_edge.dest);//dest
		
		//if no cycle put in result
		if(x!=y){
			result[e]=next_edge;
			e++;//to next result
			Union(subsets,x,y);//if no cycle,union
		}
	}
	//print src,dest,weight
printf(
        "Following are the edges in the constructed MST\n");
	int minWeight=0;
	for(i=0;i<e;i++){//print out all e
		printf("%d---%d:%d\n",result[i].src,result[i].dest,result[i].weight);
		minWeight+=result[i].weight;
		
	}
	printf("minWeight:%d",minWeight);
		
}

int main(){
	/* Let us create following weighted graph
             10
        0--------1
        |  \     |
       6|   5\   |15
        |      \ |
        2--------3
            4       */
    int V = 4; // Number of vertices in graph
    int E = 5; // Number of edges in graph
    struct Graph* graph = createGraph(V, E);
 
    // add edge 0-1
    graph->edge[0].src = 0;
    graph->edge[0].dest = 1;
    graph->edge[0].weight = 10;
 
    // add edge 0-2
    graph->edge[1].src = 0;
    graph->edge[1].dest = 2;
    graph->edge[1].weight = 6;
 
    // add edge 0-3
    graph->edge[2].src = 0;
    graph->edge[2].dest = 3;
    graph->edge[2].weight = 5;
 
    // add edge 1-3
    graph->edge[3].src = 1;
    graph->edge[3].dest = 3;
    graph->edge[3].weight = 15;
 
    // add edge 2-3
    graph->edge[4].src = 2;
    graph->edge[4].dest = 3;
    graph->edge[4].weight = 4;
 
    KruskalMST(graph);
 
    return 0;
}


```
## Prim's algorithm MST
```c=
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
// Number of vertices in the graph
#define V 5
void printMST(int parent[], int graph[V][V])//MST store in parent
{
    printf("Edge \tWeight\n");
    for (int i = 1; i < V; i++)
        printf("%d - %d \t%d \n", parent[i], i, graph[i][parent[i]]);
}

int minKey(int key[],bool mstSet[]){
	int min=INT_MAX,min_index;
	
	for(int v=0;v<V;v++){
		if(key[v]<min&&mstSet[v]==false){
			min=key[v];
			min_index=v;
		}
	}
	return min_index;
}

void primMST(int graph[V][V]){
	int parent[V];//min_index
	int key[V];//min
	bool mstSet[V];
	//initialize
	for(int i=0;i<V;i++){
		key[i]=INT_MAX;
		mstSet[i]=false;
	}
	 
	key[0] = 0;
    parent[0] = -1; // First node is always root of MST
    
    
	//minKey and add to parent
	for(int i=0;i<V-1;i++){//edge
	
		int u=minKey(key,mstSet);
		mstSet[u]=true;
		
		for(int v=0;v<V;v++){//matrix number
			//graph weight push in key
		if(mstSet[v]==false && graph[u][v] && graph[u][v]<key[v]){//update key
			parent[v]=u;
			key[v]=graph[u][v];
		}
		}
	}
	printMST(parent,graph);

};
int main()
{
    /* Let us create the following graph
        2 3
    (0)--(1)--(2)
    | / \ |
    6| 8/ \5 |7
    | /     \ |
    (3)-------(4)
            9         */
    int graph[V][V] = { { 0, 2, 0, 6, 0 },
                        { 2, 0, 3, 8, 5 },
                        { 0, 3, 0, 0, 7 },
                        { 6, 8, 0, 0, 9 },
                        { 0, 5, 7, 9, 0 } };
 
    // Print the solution
    primMST(graph);
 
    return 0;
}

```