数据结构之C++实现最小生成树克鲁斯卡尔(Kruskal)算法
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <ctime>
using namespace std;
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
#define MAXEDGE 20
#define MAXVEX 20
#define GRAPH_INFINITY 65535
typedef struct
{
int begin;
int end;
int weight;
}Edge; /* 对边集数组Edge结构的定义 */
class MGraph
{
public:
MGraph();
~MGraph();
void CreateMGraph(void);
/* 交换权值 以及头和尾 */
void Swapn(int i, int j);
/* 对权值进行排序 */
void sort(void);
/* 查找连线顶点的尾部下标 */
int Find(int f);
/* 生成最小生成树 */
void MiniSpanTree_Kruskal(void);
private:
int arc[MAXVEX][MAXVEX];
int numVertexes, numEdges;
Edge* edges=new Edge[MAXEDGE];/* 定义边集数组,edge的结构为begin,end,weight,均为整型 */
int parent[MAXVEX];/* 定义一数组用来判断边与边是否形成环路 */
};
MGraph::MGraph()
{
numVertexes=0;
numEdges=0;
for(int i=0;i<MAXVEX;i++)
{
for(int j=0;j<MAXVEX;j++)
{
if (i==j) arc[i][j]=0;
else arc[i][j]=GRAPH_INFINITY;
}
}
//for(int i=0;i<MAXEDGE;i++) edges[i]=new Edge;
}
MGraph::~MGraph()
{
delete [] edges;
}
void MGraph::CreateMGraph(void)
{
int i, j;
/* printf("请输入边数和顶点数:"); */
numEdges=15;
numVertexes=9;
arc[0][1]=10;
arc[0][5]=11;
arc[1][2]=18;
arc[1][8]=12;
arc[1][6]=16;
arc[2][8]=8;
arc[2][3]=22;
arc[3][8]=21;
arc[3][6]=24;
arc[3][7]=16;
arc[3][4]=20;
arc[4][7]=7;
arc[4][5]=26;
arc[5][6]=17;
arc[6][7]=19;
for(i = 0; i < numVertexes; i++)
{
for(j = i; j < numVertexes; j++)
{
arc[j][i] =arc[i][j];
}
}
}
void MGraph::Swapn(int i,int j)
{
int temp;
temp = edges[i].begin;
edges[i].begin = edges[j].begin;
edges[j].begin = temp;
temp = edges[i].end;
edges[i].end = edges[j].end;
edges[j].end = temp;
temp = edges[i].weight;
edges[i].weight = edges[j].weight;
edges[j].weight = temp;
}
void MGraph::sort(void)
{
int i, j;
//排序算法
for(i=0;i<numEdges;i++)
{
for (j=i+1;j<numEdges;j++)
{
if(edges[i].weight>edges[j].weight)
{
Swapn(i,j);
}
}
}
cout<<"权排序之后的为:"<<endl;
for(i=0; i<numEdges;i++)
{
cout<<"("<<edges[i].begin<<","<<edges[i].end<<") "<<edges[i].weight<<endl;;
}
}
int MGraph::Find(int f)
{
while(parent[f] > 0)
{
f = parent[f];
}
return f;
}
void MGraph::MiniSpanTree_Kruskal(void)
{
int i, j, n, m;
int k = 0;
/* 用来构建边集数组并排序********************* */
for ( i = 0; i < numVertexes-1; i++)
{
for (j = i + 1; j < numVertexes; j++)
{
if (arc[i][j]<GRAPH_INFINITY)
{
edges[k].begin = i;
edges[k].end = j;
edges[k].weight = arc[i][j];
k++;
}
}
}
sort();
/* ******************************************* */
for (i = 0; i < numVertexes; i++)
parent[i] = 0; /* 初始化数组值为0 */
cout<<"打印最小生成树:"<<endl;
for (i = 0; i < numEdges; i++) /* 循环每一条边 */
{
n = Find(edges[i].begin);
m = Find(edges[i].end);
if (n != m) /* 假如n与m不等,说明此边没有与现有的生成树形成环路 */
{
parent[n] = m; /* 将此边的结尾顶点放入下标为起点的parent中。 */
/* 表示此顶点已经在生成树集合中 */
cout<<"("<<edges[i].begin<<","<<edges[i].end<<") "<<edges[i].weight<<endl;
}
}
}
int main()
{
MGraph* G=new MGraph;
G->CreateMGraph();
G->MiniSpanTree_Kruskal();
delete G;
return 0;
}
版权声明:本文为mamor原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。