概述
1、采用书上第 161 页定义的图的邻接矩阵存储表示,编程实现构造最小生成树的 Prim 算法。
2、采用书上第 161 页定义的图的邻接矩阵存储表示,编程实现构造最小生成树的 Kruskal 算法。
例题一(Prim 算法实现):
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
typedef int Status;
typedef int VRType;
typedef int infoType;
typedef enum{DG,DN,UDG,UDN}GraphKind;
typedef struct ArcCell
{
VRType adj;
infoType* info;
}ArcCell,AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef char VertexType;
typedef struct
{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
GraphKind kind;
}MGraph;
typedef struct {
VertexType adjvex;
VRType lowcost;
}Closedge[MAX_VERTEX_NUM];
int LocateVex(MGraph G, char v)
{
int i;
for (int i = 0; i < G.vexnum; i++)
if (G.vexs[i] == v) return i;
return -1;
}
Status CreateDG(MGraph& G)
{
int i, j, k;
VertexType v1, v2;
printf("输入顶点数G.vexnum: "); scanf("%d", &G.vexnum);
printf("输入边数G.arcnum: "); scanf("%d", &G.arcnum);
getchar();
for (i = 0; i < G.vexnum; i++)
{
printf("输入顶点G.vexs[%d]:", i);
scanf("%c", &G.vexs[i]);
getchar();
}
for (i = 0; i < G.vexnum; i++)
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = 0;
G.arcs[i][j].info = NULL;
}
for (k = 0; k < G.arcnum; k++)
{
printf("输入第%d条边vi、vj:n", k + 1);
scanf("%c %c", &v1, &v2);
getchar();
i = LocateVex(G, v1); j = LocateVex(G, v2);
G.arcs[i][j].adj = 1;
}
return OK;
}
Status CreateUDG(MGraph& G)
{
int i, j, k;
VertexType v1, v2;
printf("输入顶点数G.vexnum: "); scanf("%d", &G.vexnum);
printf("输入边数G.arcnum: "); scanf("%d", &G.arcnum);
getchar();
for (i = 0; i < G.vexnum; i++)
{
printf("输入顶点G.vexs[%d]:", i);
scanf("%c", &G.vexs[i]);
getchar();
}
for (i = 0; i < G.vexnum; i++)
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = 0;
G.arcs[i][j].info = NULL;
}
for (k = 0; k < G.arcnum; k++)
{
printf("输入第%d条边vi、vj:n", k + 1);
scanf("%c %c", &v1, &v2);
getchar();
i = LocateVex(G, v1); j = LocateVex(G, v2);
G.arcs[i][j].adj = 1;
G.arcs[j][i].adj = G.arcs[i][j].adj;
}
return OK;
}
Status CreateUDN(MGraph& G)
{
int i, j, k, w;
VertexType v1, v2;
printf("输入顶点数G.vexnum: "); scanf("%d", &G.vexnum);
printf("输入边数G.arcnum: "); scanf("%d", &G.arcnum);
getchar();
for (i = 0; i < G.vexnum; i++)
{
printf("输入顶点G.vexs[%d]:",i);
scanf("%c", &G.vexs[i]);
getchar();
}
for(i=0;i<G.vexnum;i++)
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = INFINITY;
G.arcs[i][j].info = NULL;
}
for (k = 0; k < G.arcnum; k++)
{
printf("输入第%d条边vi、vj和权值w(int):n", k + 1);
scanf("%c %c %d", &v1, &v2, &w);
getchar();
i = LocateVex(G, v1); j = LocateVex(G, v2);
G.arcs[i][j].adj = w;
G.arcs[j][i].adj = G.arcs[i][j].adj;
}
return OK;
}
Status CreateDN(MGraph& G)
{
int i, j, k, w;
VertexType v1, v2;
printf("输入顶点数G.vexnum: "); scanf("%d", &G.vexnum);
printf("输入边数G.arcnum: "); scanf("%d", &G.arcnum);
getchar();
for (i = 0; i < G.vexnum; i++)
{
printf("输入顶点G.vexs[%d]:", i);
scanf("%c", &G.vexs[i]);
getchar();
}
for (i = 0; i < G.vexnum; i++)
for (j = 0; j < G.vexnum; j++)
{
G.arcs[i][j].adj = INFINITY;
G.arcs[i][j].info = NULL;
}
for (k = 0; k < G.arcnum; k++)
{
printf("输入第%d条边vi、vj和权值w(int):n", k + 1);
scanf("%c %c %d", &v1, &v2, &w);
getchar();
i = LocateVex(G, v1); j = LocateVex(G, v2);
G.arcs[i][j].adj = w;
}
return OK;
}
Status CreateGraph(MGraph& G)
{
printf("请输入图的种类:0表示DG,1表示DN,2表示UDG,3表示UDNn");
scanf("%d", &G.kind);
switch (G.kind)
{
case DG:return CreateDG(G);
case DN:return CreateDN(G);
case UDG:return CreateUDG(G);
case UDN:return CreateUDN(G);
default:return ERROR;
}
}
void list(MGraph G)
{
int i, j;
printf("输出邻接矩阵:n");
for (i = 0; i < G.vexnum; i++)
{
printf("%c----", G.vexs[i]);
for (j = 0; j < G.vexnum; j++)
if (G.arcs[i][j].adj == INFINITY)
{printf("%4s", "∞"); }
else
printf("%4d", G.arcs[i][j].adj);
printf("n");
}
}
Status minimum(MGraph G,Closedge closedge)
{
int i, j;
double k = 1000;
for (i = 0; i < G.vexnum; i++)
{
if (closedge[i].lowcost != 0 && closedge[i].lowcost < k)
{
k = closedge[i].lowcost;
j = i;
}
}
return j;
}
void MiniSpanTree_PRIM(MGraph G, VertexType u) {
int i, j,k;
Closedge closedge;
k = LocateVex(G, u);
for (j = 0; j < G.vexnum; ++j)
if (j != k) closedge[j] = { u,G.arcs[k][j].adj };
closedge[k].lowcost = 0;
for (i = 1; i < G.vexnum; ++i)
{
k = minimum(G,closedge);
printf("%c%c ",closedge[k].adjvex, G.vexs[k]);
closedge[k].lowcost = 0;
for (j = 0; j < G.vexnum;++j)
if (G.arcs[k][j].adj < closedge[j].lowcost)
closedge[j] = { G.vexs[k],G.arcs[k][j].adj };
}
}
int main()
{
MGraph G;
CreateGraph(G);
list(G);
printf("输出最小生成树:n");
MiniSpanTree_PRIM(G, 'A');
printf("n");
}
例题二(Kruskal 算法实现):
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define INFINITY INT_MAX
#define MAX_VERTEX_NUM 20
typedef int Status;
typedef int VRType;
typedef int infoType;
typedef char VertexType;
typedef struct ArcCell
{
VRType adj;
VertexType start, finish;
}ArcCell, AdjMatrix[MAX_VERTEX_NUM];
typedef struct
{
VertexType vexs[MAX_VERTEX_NUM];
AdjMatrix arcs;
int vexnum, arcnum;
}MGraph;
int LocateVex(MGraph G, char v)
{
int i;
for (int i = 0; i < G.vexnum; i++)
if (G.vexs[i] == v) return i;
return -1;
}
Status CreateGraph(MGraph& G)
{
int i, j, k, w;
VertexType v1, v2;
printf("输入顶点数G.vexnum: "); scanf("%d", &G.vexnum);
printf("输入边数G.arcnum: "); scanf("%d", &G.arcnum);
getchar();
for (i = 0; i < G.vexnum; i++)
{
printf("输入顶点G.vexs[%d]:", i);
scanf("%c", &G.vexs[i]);
getchar();
}
for (k = 0; k < G.arcnum; k++)
{
printf("输入第%d条边vi、vj和权值w(int):n", k + 1);
scanf("%c %c %d", &v1, &v2, &w);
getchar();
G.arcs[k].start = v1; G.arcs[k].finish = v2;
G.arcs[k].adj = w;
}
for (i = 0; i < G.arcnum-1; i++)
{
for (j = i + 1; j < G.arcnum; j++)
{
ArcCell Temp;
if (G.arcs[i].adj > G.arcs[j].adj)
{
Temp = G.arcs[i]; G.arcs[i] = G.arcs[j]; G.arcs[j] = Temp;
}
}
}
return OK;
}
Status FindStuation(int partern[], int e)
{
while (partern[e] != 0)
{
e = partern[e];
}
return e;
}
Status FinishFind(MGraph& G, int partern[])
{
int i, num = 0;
for (i = 0; i < G.vexnum; i++)
{
if (partern[i]) num++;
}
if (num == G.vexnum - 1) return OK;
return FALSE;
}
Status MiniSpanTree_Kruskal(MGraph& G)
{
int i, sit, hit;
int partern[MAX_VERTEX_NUM];
for (i = 0; i < G.vexnum; i++)
{
partern[i] = 0;
}
for (i = 0; i < G.arcnum; i++)
{
sit = FindStuation(partern,LocateVex(G,G.arcs[i].start));
hit = FindStuation(partern,LocateVex(G,G.arcs[i].finish));
if (sit != hit)
{
partern[sit] = hit;
printf("%c%c ", G.arcs[i].start, G.arcs[i].finish);
}
if(FinishFind(G,partern)) return OK;
}
}
int main()
{
MGraph G;
CreateGraph(G);
printf("输出最小生成树:n");
MiniSpanTree_Kruskal(G);
printf("n");
}
最后
以上就是幽默小笼包为你收集整理的图的最小生成树算法实现(Prim + Kruskal)的全部内容,希望文章能够帮你解决图的最小生成树算法实现(Prim + Kruskal)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复