大话数据结构
Unit6 图
邻接矩阵的最小生成树Kruskal算法
代码
#include <iostream>
typedef char VertexType;
typedef int EdgeType;
#define MAXVEX 100
#define MAXEDGE 10
#define INFINITY 65535
using namespace std;
int visited[100];
//构建顶点表
typedef struct {
VertexType vexs[MAXVEX]; //顶点数组
EdgeType arc[MAXVEX][MAXVEX]; //边的矩阵表示
int numVertexes, numEdges; //图中当前的顶点数和边数
}MGraph;
//创建邻接矩阵
MGraph* CreatMgraph(MGraph* G) {
int i, j, k, w;
cout << "输入顶点数和边数:" << endl;
cin >> G->numVertexes >> G->numEdges;
for (i = 0;i < G->numVertexes;i++) {
cout << "请输入顶点名:" << endl;
cin >> G->vexs[i];
}
//初始化邻接矩阵
for (i = 0;i < G->numVertexes;i++) {
for (j = 0;j < G->numVertexes;j++) {
G->arc[i][j] = INFINITY;
}
}
//构建邻接矩阵
for (k = 0;k < G->numEdges;k++) {
cout << "输入边(vi,vj)上的下标i,下标j和权w:" << endl;
cin >> i >> j >> w;
G->arc[i][j] = w;
G->arc[j][i] = G->arc[i][j];
}
return G;
}
//对边集数组结构的定义
typedef struct
{
int begin;
int end;
int weight;
}Edge;
void swap(Edge e[],int i,int j ) {
Edge temp;
temp.begin = e[i].begin;
temp.end = e[i].end;
temp.weight = e[i].weight;
e[i].begin = e[j].begin;
e[i].end = e[j].end;
e[i].weight = e[j].weight;
e[j].begin = temp.begin;
e[j].end = temp.end;
e[j].weight = temp.weight;
}
void printf_edge(Edge* E) {
for (int i = 0;i < 5;i++) {
cout << E[i].begin << " " << E[i].end << " " << E[i].weight << endl;
}
}
int Find(int* parent, int f) {//查找连线顶点的尾部下标
while (parent[f] > 0) {
f = parent[f];
return f;
}
}
Edge* sort(MGraph G) {
static Edge edges[5];
int i, j,k = 0;
for (int i = 0;i < G.numVertexes;i++) {
for (int j = i;j < G.numVertexes;j++) {
if (G.arc[i][j] != 0 && G.arc[i][j] != 65535) {
edges[k].begin = i;
edges[k].end = j;
edges[k].weight = G.arc[i][j];
++k;
//cout << edges[i].begin << " " + edges[i].end << " " + edges[i].weight << endl;
}
}
}
//排序
for (i = 0;i < G.numVertexes;i++) {
for (j = i+1;j< G.numVertexes;j++) {
if (edges[j].weight < edges[i].weight)
{
swap(edges, i, j);
}
}
}
//printf_edge(edges);
return edges;
}
//Kruskal算法生成最小生成树
void MiniDpanTree_Kruskal(MGraph G) {
int i, n, m;
//Edge edges[MAXEDGE];//定义边集数组
int parent[MAXVEX];//定义一组数来判断边与边是否形成回路
//此处省略将邻接矩阵G转化为边集数组edges并按权重由小到大排序的代码
Edge *edges = sort(G);
cout << "边集数组为" << endl;
printf_edge(edges);
for (i = 0;i < G.numVertexes;i++) {
parent[i] = 0;//初始化数组值为0
}
//循环每一条边
cout << "最小生成树为" << endl;
for (i = 0;i < G.numEdges;i++) {
n = Find(parent, edges[i].begin);
m = Find(parent, edges[i].end);
if (n != m) {//若m!=n说明未形成回路
parent[n] = m;//将此边的结尾点放入下标为顶点的parent中,表示此顶点已经在生成树中
cout << edges[i].begin<<" "<<edges[i].end << " "<<edges[i].weight<<"->";
}
}
}
int main() {
MGraph* grap = (MGraph*)malloc(sizeof(MGraph));
MGraph* G = CreatMgraph(grap);
//sort(*G);
MiniDpanTree_Kruskal(*grap);
//printf_edge(edges);
free(grap);
grap = NULL;
return 0;
}
运行结果