kruskal与prim最小生成树算法

以下代码未经验证:

#include<vector>
#include<algorithm>
using namespace std;
#define MAXINT 0xffff
#define vertexNum 10
typedef struct Graph
{
	int border[vertexNum][vertexNum];
}Graph;

typedef struct border
{
	int v1;	//第一个顶点
	int v2;	//第二个顶点
	int weight;	//权重
}BORDER;	//边结构

Graph G;
bool cmp(BORDER a, BORDER b)	//作为排序回调函数,按权重对结构体从小到大排序
{
	return a.weight < b.weight;
}
vector<BORDER> minTree;
void Kruskal()
{
	vector<BORDER> b;
	BORDER temp;
	for(int i = 0; i < vertexNum - 1; i++)	//列出所有边并存储进边结构
	{
		for(int j = i + 1; j < vertexNum; j++)
		{
			if(G.border[i][j] < MAXINT)
			{
				temp = { i, j, G.border[i][j] };
				b.push_back(temp);
			}
		}
	}
	sort(b.begin(), b.end(), cmp);	//对所有边按权重由小到大排序
	int bSet[vertexNum] = { 0 };	//初始时每个顶点都为独立的树,对应集合不同
	for(int i = 0; i < vertexNum; i++)
	{
		bSet[i] = i;	//bSet[]所有i对应的值不相同,索性就都等于i,下标肯定不同,所以值不同。后续把i1,i2值设为相同的话,则意味着,i1,i2在同一个集合(树)
	}
	int size = b.size;
	for(int i = 0; i < size; i++)
	{
		if(bSet[b[i].v1] != bSet[b[i].v2])	//如果该边的两个顶点不在同一个集合(树)
		{
			minTree.push_back(b[i]);	//把该边存到结果集
			for(int j = 0; j < vertexNum; j++)	
			{
				if(bSet[j] == bSet[b[i].v1])	//找出b[i].v1所在集合的所有点
				{
					bSet[j] = bSet[b[i].v2];	//把b[i].v1这个点所在集合的所有的点都放到bSet[i].v2所在集合,其实就是合并这个两个点所在集合
				}
			}
		}
	}
}

prim算法代码如下,未经验证:

vector<BORDER> borders;
void prim()
{
	bool isVisited[vertexNum] = {0};
	int curVertex = 0, curNextVertex = 0;
	isVisited[curVertex] = true;
	int minBorder = MAXINT;
	BORDER temp;
	int vistedBCount = 0;
	while( vistedBCount < vertexNum - 1)
	{
		for (int i = 1; i < vertexNum; i++)
		{
			if (curVertex != i && G.border[curVertex][i] < minBorder && isVisited[i] == false)
			{
				minBorder = G.border[curVertex][i];
				curNextVertex = i;
			}
		}
		temp.v1 = curVertex;
		temp.v2 = curNextVertex;
		temp.weight = minBorder;
		borders.push_back(temp);
		curVertex = curNextVertex;
		vistedBCount++;
	}
}




猜你喜欢

转载自blog.csdn.net/m0_37907835/article/details/79054544
今日推荐