#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<limits.h>
#define MAX_VERTEX_NUM 20
typedef enum{DG, DN, UDG, UDN} GraphKind;
typedef int VRType;//边的信息
typedef char VertexType;//顶点的信息
typedef struct ArcCell{
VRType adj;//保存边的权值
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];//图的邻接矩阵,保存边的信息
typedef struct{
VertexType vex[MAX_VERTEX_NUM];//保存顶点的信息,在本图中,顶点的信息由字符表示
AdjMatrix arcs;//图的邻接矩阵
int vexnum, arcnum;//保存图的顶点数和边数
GraphKind kind;//图的种类
}MGraph;
typedef struct{//辅助数组,记录U到V-U的代价最小的边的辅助数组
VertexType adjvex;//顶点集U到该点为最小权值的那个顶点的序号
VRType lowcost;//上面adjvex顶点到这个顶点的最小权值
}minside[MAX_VERTEX_NUM];
int LocateVex(MGraph G, VertexType u){//寻找顶点在图中的序号
int i = 0;
for(i = 0; i < G.vexnum; i++)
if(G.vex[i] == u)
return i;
return -1;
}
int minimum(minside SZ, MGraph G){//在辅助数组中找到权值最小的边
int i, j, min, k;
for(i = 0; SZ[i].lowcost==0; i++)//找到第一个不为0的SZ[i].lowcost的位置
;
min = SZ[i].lowcost;
k = i;
for(j = 0; j < G.vexnum; j++)
if(SZ[j].lowcost > 0 && SZ[j].lowcost < min){
min = SZ[j].lowcost;
k = j;
}
return k;
}
void MiniSpanTree_Prim(MGraph G, VertexType u){
minside closedge;//定义辅助数组
int i, j;
int k = LocateVex(G, u);
for(j = 0; j < G.vexnum; j++)//辅助数组初始化,此时讲u这个点包含到U中。
if(j != k){
closedge[j].adjvex = u;//此时数组中距离都是顶点u到其它所有结点的距离
closedge[j].lowcost = G.arcs[k][j].adj;//顶点u到所有结点的权值
}
closedge[k].lowcost = 0;//值为0表示该点以进入到集合U中
printf("最小代价生成树的各条边为\n");
for(i = 1; i < G.vexnum; i++){
k = minimum(closedge,G);
printf("加入的第%d条为%c到%c\n", i, closedge[k].adjvex, G.vex[k]);
closedge[k].lowcost = 0;//值为k的结点进如U中
for(j = 0; j < G.vexnum; j++)//与k相关联的结点,如果U中k节点到V-U的结点距离小于以前的距离,则修改辅助数组的值
if(G.arcs[k][j].adj < closedge[j].lowcost)
{
closedge[j].adjvex = G.vex[k];
closedge[j].lowcost = G.arcs[k][j].adj;
}
}
}
int main()
{
FILE * p_file;
if(!(p_file = fopen("D:\\test.txt","r")))
{
printf("open error\n");
return 0;
}
int i, j;
MGraph G;
G.kind = DG;
G.arcnum = 10;
G.vexnum = 6;
for(i = 0; i< G.vexnum;i++)
G.vex[i] = (char)(97 + i);
char tail[MAX_VERTEX_NUM], head[MAX_VERTEX_NUM];//保存所有边的起始位置和终点位置
int cost[MAX_VERTEX_NUM];//保存相对应边的权值
for(i = 0; i < G.arcnum;i++)
{
fscanf(p_file, "%c%c%d",&tail[i], &head[i], &cost[i]);
}
for(i = 0; i < G.vexnum;i++)
for(j = 0; j < G.vexnum; j++)
G.arcs[i][j].adj = SHRT_MAX;
for(i = 0; i < G.arcnum;i++){
int m = LocateVex(G, tail[i]);
int n = LocateVex(G, head[i]);
G.arcs[m][n].adj = cost[i];
G.arcs[n][m].adj = cost[i];
}
for(i = 0; i < G.vexnum;i++){
for(j = 0; j < G.vexnum; j++)
printf("%6d ",G.arcs[i][j].adj);
printf("\n");
}
MiniSpanTree_Prim(G, 'a');
}
txtz中保存的数据如下,ab6be3ef6fd2da5ac1bc5dc5ec6fc4。
其中v1到v6在代码中用点a到点f来表示。如代码有错误,望不吝赐教!