最小生成樹Prim筆記

計算最小生成樹的一種方法就是使其連續的一步一步的長成。在每一步都要把一個結點當做根來往上加邊。在算法的任一時刻都可以看到一組已經添加到樹上的頂點,而其餘頂點尚未加到這棵樹上。就找尚未加到這個樹上的頂點到已經加到樹上的頂點的最小的權值。
在這裏插入圖片描述
以v1作爲起始點,這時v4與v1的權值最小,那麼就把v1和v4連上;
然後在其他沒有被連在樹上的頂點中找到了v2裏v1權值是2,v3離v4權值是2,這兩個最小,那麼就再把v2和v3加入到樹中;
接下來在剩下沒有加到樹中的有v5,v6,v7,可以看到v7離已經被到樹中的v4的權值是4,這是最小的,那就把v7連進去;
這時候剩v5和v6,v6離已經被到樹中的v7的權值是1,這是最小的,所以把這條連進去;
最後v5與個點中權值最小的是v5和v7爲6,連進去。
在這裏插入圖片描述
結果就是這樣。

上代碼:

#include<stdio.h>
#include<stdlib.h>

#define MAXVEX 7
#define INFINITY 65535 //代表無窮大

typedef struct 
{
	char vex[MAXVEX];
	int arc[MAXVEX][MAXVEX];
	int vertex,edge;  //頂點數量和邊的數量
}Graph;

//創建鄰接矩陣
void createGra(Graph *g)
{
	int i,j;
	printf("請輸入頂點數量和邊的數量:\n");
	scanf("%d %d",&g->vertex,&g->edge);
	printf("輸入頂點元素\n");
	for(i=0;i<g->vertex;i++)
	{
		getchar();
		scanf("%c",&g->vex[i]);
	}
	//建立矩陣
	printf("如果有連線就輸入其權值,i與j相等的時候是0,否則是無窮大:\n");
	for(i=0;i<g->vertex;i++)
	{
		for(j=0;j<g->vertex;j++)
		{
			scanf("%d",&g->arc[i][j]);
		}
	}
}

//輸出鄰接矩陣
void print(Graph g)
{
	int i,j;
	for(i=0;i<g.vertex;i++)
	{
		for(j=0;j<g.vertex;j++)
		{
			printf("%8d ",g.arc[i][j]);
		}
		printf("\n");
	}
	printf("\n");
	
}

//prim算法

void prim(Graph g)
{
	int i,j,k,sum=0;
	int min;
	int adjvex[MAXVEX];   //保存相關頂點
	int lowcost[MAXVEX];   //保存已經連接了的頂點的權值

	//初始化,從下標是0的頂點開始
	for(i=0;i<g.vertex;i++)
	{
		adjvex[i]=0;
		lowcost[i]=g.arc[0][i];    //存第一個頂點的所有的權值
	}

	for(i=0;i<g.vertex;i++)
	{
		min = INFINITY;
		j=1;
		k=0;
		while(j<g.vertex)
		{
			if(lowcost[j]!=0 && lowcost[j]<min)
			{
				min=lowcost[j];              //找到與頂點相連的最小的權值下標
				k=j;
			}
			j++;
		}
		if(min!=INFINITY)                     //一開始沒有加這個if 但是結果發現多出來一個(0,0),權值多出65535,調試發現是最後一次循環又把min初始化然後輸出了
		{
			printf("(%d,%d) ",adjvex[k],k);
		    lowcost[k]=0;          //表明k下標已經是遍歷過了的,接下來遍歷就不會找到k和i邊了
		    printf("權值爲:%d",min);
		    sum=sum+min;
		}

		for(j=1;j<g.vertex;j++)
		{
			if(lowcost[j]!=0 && g.arc[k][j]<lowcost[j])
			{
				lowcost[j]=g.arc[k][j];          //找到已經遍歷了的頂點和沒有遍歷的的頂點的權值較小的存到了lowcost中,
				adjvex[j]=k;          //作爲等會打印的上一個頂點
			}
		}
	}
	printf("\n最小權值和爲%d\n",sum);

}

int main()
{
	Graph g;
	createGra(&g);
	print(g);
	prim(g);
	return 0;
}

在這裏插入圖片描述

學習《數據結構與算法分析》的筆記。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章