1. 程式人生 > 實用技巧 >重新整理資料結構與演算法(c#)——演算法套路普利姆演算法[二十九]

重新整理資料結構與演算法(c#)——演算法套路普利姆演算法[二十九]

前言

看一個題目:

這個問題就是求最小生成樹,是圖轉換為樹的一種方式。

最小生成樹概念:

最小生成樹簡稱MST。

1.n個頂點,一定有n-1條邊

2.包含全部頂點。

3.圖轉換為最小生成樹,權重之和最小。

解題思路:

  1. 假設從a開始為頂點,找到和a相接的最小邊。

  2. 在圖中和a相接的是G,那麼選擇條。然後找到和A、G相接的最小邊,是BG,然後選擇BG這條邊。

  3. 以此類推。

正文

程式碼:

static void Main(string[] args)
{
	char[] data = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G' };
	int verxs = data.Length;
	//鄰接矩陣的關係使用二維陣列表示,10000這個大數,表示兩個點不聯通
	int[,] weight = new int[,]{
	{10000,5,7,10000,10000,10000,2},
	{5,10000,10000,9,10000,10000,3},
	{7,10000,10000,10000,8,10000,10000},
	{10000,9,10000,10000,10000,4,10000},
	{10000,10000,8,10000,10000,5,4},
	{10000,10000,10000,4,5,10000,6},
	{2,3,10000,10000,4,6,10000},};
	//建立要修的路,初始化節點的個數
	MGraph mGraph = new MGraph(verxs);
	//建立一個MinTree物件
	MinTree minTree = new MinTree();
	minTree.createGraph(mGraph, verxs, data, weight);
	Console.WriteLine("顯示原始圖");
	minTree.showGraph(mGraph);
	var newGraph=minTree.prim(mGraph, 0);
	Console.WriteLine("顯示最小生成樹圖");
	minTree.showGraph(newGraph);
	Console.Read();
} 
}

class MinTree {
//不汙染資料
public void createGraph(MGraph mGraph, int verxs, char[] data, int[,] weight)
{
	for (int i = 0; i < verxs; i++)
	{
		mGraph.data[i] = data[i];
		for (int j = 0; j < verxs; j++)
		{
			mGraph.weight[i,j] = weight[i,j];
		}
	}
}
//遍歷圖
public void showGraph(MGraph mGraph)
{
	for (int i=0;i<mGraph.verxs;i++)
	{
		for (int j = 0; j < mGraph.verxs; j++)
		{
			Console.Write(mGraph.weight[i,j]+"  ");
		}
		Console.WriteLine();
	}
}

/// <summary>
/// 圖轉樹核心演算法
/// </summary>
/// <param name="mGraph">原始圖</param>
/// <param name="v">初始化訪問節點</param>
public MGraph prim(MGraph mGraph,int v)
{
	int[] isVisited = new int[mGraph.verxs];
	isVisited[v] = 1;
	int y = -1;//y為陣列豎軸
	int x = -1;//x為陣列橫軸
	MGraph newGraph = new MGraph(mGraph.verxs);
	newGraph.data = (char[])mGraph.data.Clone();
	int minWeight = 1000;
	//一共要計算出verxs-1條邊
	for (int k=1;k<mGraph.verxs;k++)
	{
		for (int i=0;i<mGraph.verxs;i++)
		{
			for (int j = 0; j < mGraph.verxs ; j++)
			{
				if (isVisited[i] == 1 && isVisited[j] == 0 && mGraph.weight[i, j] < minWeight)
				{
					y = i;
					x = j;
					minWeight = mGraph.weight[i, j];
				}
			}
		}
		Console.WriteLine("在"+mGraph.data[y]+"和"+ mGraph.data[x]+"之間修了一條權重為"+minWeight+"的路");
		newGraph.weight[y,x] = minWeight;
		isVisited[x] = 1;
		minWeight = 1000;
	}
	return newGraph;
}
}

結果: