当前位置:文档之家› 最小生成树的Kruskal算法实现

最小生成树的Kruskal算法实现

#include<stdio.h>
#include<stdlib.h>
#define M 20
#define MAX 20
typedef struct
{
int begin;
int end;
int weight;
}edge;
typedef struct
{
int adj;
int weight;
}AdjMatrix[MAX][MAX];
typedef struct
{
AdjMatrix arc;
int vexnum, arcnum;
}MGraph;
void CreatGraph(MGraph *);//函数申明
void sort(edge* ,MGraph *);
void MiniSpanTree(MGraph *);
int Find(int *, int );
void Swapn(edge *, int, int);
void CreatGraph(MGraph *G)//构件图
{
int i, j,n, m;
printf("请输入边数和顶点数:\n");
scanf("%d %d",&G->arcnum,&G->vexnum);
for (i = 1; i <= G->vexnum; i++)//初始化图{
for ( j = 1; j <= G->vexnum; j++)
{
G->arc[i][j].adj = G->arc[j][i].adj = 0;
}
}
for ( i = 1; i <= G->arcnum; i++)//输入边和权值
{
printf("请输入有边的2个顶点\n");
scanf("%d %d",&n,&m);
while(n < 0 || n > G->vexnum || m < 0 || n > G->vexnum) {
printf("输入的数字不符合要求请重新输入:\n");
scanf("%d%d",&n,&m);
}
G->arc[n][m].adj = G->arc[m][n].adj = 1;
getchar();
printf("请输入%d与%d之间的权值:\n", n, m);
scanf("%d",&G->arc[n][m].weight);
}
printf("邻接矩阵为:\n");
for ( i = 1; i <= G->vexnum; i++)
{
for ( j = 1; j <= G->vexnum; j++)
{
printf("%d ",G->arc[i][j].adj);
}
printf("\n");
}
}
void sort(edge edges[],MGraph *G)//对权值进行排序{
int i, j;
for ( i = 1; i < G->arcnum; i++)
{
for ( j = i + 1; j <= G->arcnum; j++)
{
if (edges[i].weight > edges[j].weight)
{
Swapn(edges, i, j);
}
}
}
printf("权排序之后的为:\n");
for (i = 1; i < G->arcnum; i++)
{
printf("<< %d, %d >> %d\n", edges[i].begin, edges[i].end, edges[i].weight); }
}
void Swapn(edge *edges,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 MiniSpanTree(MGraph *G)//生成最小生成树
{
int i, j, n, m;
int k = 1;
int parent[M];
edge edges[M];
for ( i = 1; i < G->vexnum; i++)
{
for (j = i + 1; j <= G->vexnum; j++)
{
if (G->arc[i][j].adj == 1)
{
edges[k].begin = i;
edges[k].end = j;
edges[k].weight = G->arc[i][j].weight;
k++;
}
}
}
sort(edges, G);
for (i = 1; i <= G->arcnum; i++)
{
parent[i] = 0;
}
printf("最小生成树为:\n");
for (i = 1; i <= G->arcnum; i++)//核心部分
{
n = Find(parent, edges[i].begin);
m = Find(parent, edges[i].end);
if (n != m)//判断是否有回路,如果有,舍弃
{
parent[m] = n;
printf("<< %d, %d >> %d\n", edges[i].begin, edges[i].end, edges[i].weight); }
}
}
int Find(int *parent, int f)//找尾
{
while ( parent[f] > 0)
{
f = parent[f];
}
return f;
}
int main(void)//主函数
{
MGraph *G;
G = (MGraph*)malloc(sizeof(MGraph));
if (G == NULL)
{
printf("memory allcation failed,goodbye");
exit(1);
}
CreatGraph(G);
MiniSpanTree(G);
system("pause");
return 0;
}
/%BD%F5%B1%F3ljb/blog/item/7bce9a339f74f049ac4b5f30.html
#include "heap.h"
#include "UFSets.h"
template <class T, class E>
void Kruskal (Graph<T, E>& G,
MinSpanTree<T, E>& MST) {
MSTEdgeNode<T, E> ed; //边结点辅助单元
int u, v, count;
int n = G.NumberOfVertices(); //顶点数
int m = G.NumberOfEdges(); //边数
MinHeap <MSTEdgeNode<T, E>> H(m); //最小堆
UFSets F(n); //并查集
for (u = 0; u < n; u++)
for (v = u+1; v < n; v++)
if (G.getWeight(u,v) != maxValue) {
ed.tail = u; ed.head = v; //插入堆
ed.cost = G.getWeight (u, v);
H.Insert(ed);
count = 1; //最小生成树边数计数
while (count < n) { //反复执行, 取n-1条边
H.Remove(ed); //退出具最小权值的边
u = F.Find(ed.tail); v = F.Find(ed.head);
//取两顶点所在集合的根u与v
if (u != v) { //不是同一集合,不连通
F.Union(u, v); //合并,连通它们
MST.Insert(ed); //该边存入MST
count++;
}
}
};。

相关主题