Prim演算法(最小生成樹) 我TM只能先做到這兒了 後面繼續補充

PengPengBlog發表於2017-02-22

http://wenku.baidu.com/view/b7e730c751e2524de518964bcf84b9d529ea2c46

文庫裡面有更具體的解釋

實在不行 這個視訊解釋的也很詳細

http://v.youku.com/v_show/id_XNjg1MDk5ODM2.html?f=21855299&o=1

//鄰接矩陣的廣度遍歷演算法

void MiniSpanTree_Prim(MGraph G)
{
	int min, i, j, k;
	int adjvex[MAXVEX]; // 儲存相關頂點下標[0,0,1,0,0,0,1,0,1] 這個值表示什麼呢?表示0和0之間的連線,1:表示2和1之間有聯絡,接下來1代表頂點元素6和1之間有聯絡。 1:8和1有聯絡;因為是從1出發的頂點看看各點和1的聯絡。
	int lowcost[MAXVEX]; //存放相關頂點間邊的權值。通過好多層迭代把每一行最短的值給篩選出來。生成最小生成樹,得到都是邊和邊權值最小的連線。唯一的要求就是把所有的頂點都給連起來。

	
	lowcost[0]=0;  //v0作為最小生成樹的根開始遍歷,權值為0
	adjvex[0] = 0; //v0第一個加入

	//初始化操作
	for(i=1; i<G.numVerteses; i++)
	{
		lowcost[i] = G.arc[0][i]; //將鄰接矩陣第0行的所有權值先加入陣列。
		adjvex[i]=0;              //初始化全部先為v0的下標。
	}

	//真正構造最小生成樹的過程   分為兩個過程: 1.迴圈所有結點找出lowcost陣列已儲存的最小權值
	for(i=1; i<G.numVertexes;i++)
	{
		min = INFINITY;  //初始化最小權值為65535等不可數值;
		j = 1; 

		k = 0;
		//退出迴圈直到從1--8裡面找到真正的min。 這是給一個固定的頂點找到一個最小的值
		while(j<G.numVerteses) //j從1開始 遍歷1--8;因為下標是0--8,而0的話前面已經給初始化了。是第一個頂點已經無償作為最小生成數的根結點。
		{  
			//找出lowcost陣列已儲存的最小權值
			if(lowcost[j]!=0 && lowcost[j]<min) //lowcost[j]!=0:自己和自己連線沒意思。如果lowcost[j]<min的話,說明是有連線的。
			{
				min = lowcost[j];  //再從Lowcost中找到除自己外以及已經上次找到的最小距離的 中的 最小的權。 
				k = j//將發現的最小權值的下標存入k,以待使用;
			}
			j++;
		} 
	
		//列印當前頂點邊中權值最小的邊;
		printf("{%d,%d}=",adjvex[k],k); //adjvex 存放的是 上一個找到的頂點下邊的值。    第一次迴圈列印的結果是,adjvex[1]=0;  k==1
		lowcost[k] = 0; //將當前頂點的權值設定為0,表示此頂點已經完成任務,進行下一個頂點的遍歷;第一行權值內 只要有一個點完成任務,那麼就設定為0;


		//鄰接矩陣k行逐個遍歷全部結點;這個作用和上面不同,我們之前的lowcost初始值只有v0的這一行和vo連線點的一個權值,
		//這裡從k開始了 k的值是1,對k=這一行的遍歷,然後呢?修改lowcost的值,如果第j的小於第一行的lowcost的話,那麼就替換掉lowcost原來的值。

		for(j=0; j<G.numVertexes;j++)
		{
			if(lowcost[j]!=0 && G.arc[k][j]<lowcost[j])  //第k行的權值小於lowcost[j] lowcost依然保持著第一行的的權值。
			{
				lowcost[j] = G.arc[k][j]; //lowcost裡面所有的權值也是所替換掉的最小的權值。
				adjvex[j] = k; //將下標k的頂點填到adjvex[j]中。作為我們待會列印的上一個頂點。將每一個替換的都adjvex都給輸入進去。最終輸出的結果就是adjvex裡面所有的點都是按照順序的最小權值的點。
			}
		}
}

相關文章