//
// Prim_懒猫老师.cpp
// §6Graph
//
// Created by 郭宸羽 on 20/10/2022.
//
//
// Prim_大话数据结构_p211.cpp
// §6Graph
//
// Created by 郭宸羽 on 19/10/2022.
//
#include <stdio.h>
#include <stdlib.h>
#define INF 65535
#define MAXVEX 9
struct MGraph{
int Vertexesnum,numEdges;
int arc_matrix[MAXVEX][MAXVEX];
};
//1.临接矩阵存储图的初始化———————————————————————————————————————————-————————————————————————————————————————————————
void InitialMGraph(MGraph&G)
{
int i,j;
G.Vertexesnum = 9; G.numEdges = 15;//1.1初始化图的顶点数和图的边数
//1.2初始化图
for(i = 0; i< G.Vertexesnum; i++)
{
for(j = 0; j< G.Vertexesnum;j++)
G.arc_matrix[i][j] = INF;
}
}
//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//2.生成图的临接矩阵(临接矩阵赋值)——————————————————————————————————————————————————————————————————————————————————————
void CreateMGraph(MGraph*p_G)
{
p_G->arc_matrix[0][1]=10;
p_G->arc_matrix[0][5]=11;
p_G->arc_matrix[1][2]=18;
p_G->arc_matrix[1][8]=12;
p_G->arc_matrix[1][6]=16;
p_G->arc_matrix[2][8]=8;
p_G->arc_matrix[2][3]=22;
p_G->arc_matrix[3][8]=21;
p_G->arc_matrix[3][6]=24;
p_G->arc_matrix[3][7]=16;
p_G->arc_matrix[3][4]=20;
p_G->arc_matrix[4][7]=7;
p_G->arc_matrix[4][5]=26;
p_G->arc_matrix[5][6]=17;
p_G->arc_matrix[6][7]=19;
int i;int j;
for(i = 0; i < p_G->Vertexesnum; i++)
{
for(j = i; j < p_G->Vertexesnum; j++)
{
p_G->arc_matrix[j][i] = p_G->arc_matrix[i][j];
}
}
}
//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————
//3.Prim 生成最小生成树————————————————————————————————————————————————————————————————————————————————————————————————
void MinSpanTree_Prim(MGraph G,int root_v)
{
int lowcost[G.Vertexesnum],adjvex[G.Vertexesnum];
int i,j,sum = 0;
int k;//k用于记录lowcost数组中新并入结点
//3.1 Initial
k = root_v;
for(i= 0;i<G.Vertexesnum;i++)
{
lowcost[i] = G.arc_matrix[k][i];//1.Update(if(adjMatrix[k][j] < lowcast[j])⇒lowcast[j]=adjMatrix[k][j])
adjvex[i] = k;//更新父亲列表 也可以写为: if(lowcost[i] == INF)->adjvex[i] = NOADJ; else->lowcost[i] = G.vertex[root_v]
}
lowcost[k] = 0;
//3.2生成树
for(i = 1;i<G.Vertexesnum;i++)
{
//3.2.1查找最小结点 标记并入树中
//选择排序_遍历数组选最小值的算法 :int min = INF; for(int j = 0;j<num;j++){ if(min > lowcost[j]){ min = lowcost[j]; }
int min = INF;
for(j = 0;j<G.Vertexesnum;j++)
{
if(lowcost[j] != 0 && lowcost[j] < min)//❌更迭关系!min < lowcost[j]这条件条语句永远没法执行呀! 当前节点永远只能是0了!
{
min = lowcost[j];
k = j;//目的是为了这个也就是找到新并入结点的下表
}
}
sum += lowcost[k];
lowcost[k] = 0;//双亲成立
printf("(%d,%d) ",k,adjvex[k]);//打印的只是最新更新的
//3.2.2 由于新结点并入树中 所以要更新图的的lowcost关系,更新结点的关联数组
for(j = 0;j < G.Vertexesnum;j++)
{
if(lowcost[j] != 0 && G.arc_matrix[k][j] < lowcost[j] )
//已经并入树的顶点不考虑 //连接图中在顶点新并入树之后距离变小的顶点
{
lowcost[j] = G.arc_matrix[k][j]; //更新————新顶点并入树之后到新顶点距离变小的边
adjvex[j] = k;//改变预备新双亲(将新结点并入树导致距生成树的距离变小的顶点连接到变小的原因—————新并入的结点j上)
}
}
}
printf("sum weight of graph = %d\n",sum);
}
//—————————————————————————————————————————————————————————————————————————————————————————————————————————————————
int main()
{
MGraph G;
InitialMGraph(G);
CreateMGraph(&G);
MinSpanTree_Prim(G,0);
}
//1.两个数组 一个记录生成树结点间的关系(双亲表示法) 另一个记录每次生成树边的权值
//2.两次循环 第一次循环:初始化生成树(包括结点关系数组 和 边的权值)
// 第二次循环:生成树更新到完全生成树————外层大循环控制链接n-1个结点,内层小循环1:链接最小结点 2:更新边的权值信息
/*⚠️!为什么没有搞清楚? 1.∵lowcost数组的具体操作没有搞清楚,lowcost[i]表示以i为终点的边的最小权值✓,⚠️当lowcost[i]=0说明以i为终点的边的最小权值=0,也就是表示i点加入了MST
2.mst[i]:表示对应lowcost[i]的起点,即说明边<mst[i],i>是MST的一条边,当mst[i]=0表示起点i加入MST
*/