Prim对比Dijkstra算法
解释解释在注释及代码中已经给出。
本代码在code::blocks 17.12 可以确认运行。
#include <stdio.h>
#include <stdlib.h>
#define MAX 64
typedef struct Graph{
char* vexs[MAX];//节点名称
int AdjMartix[MAX][MAX];//邻接矩阵
int vexnum;//节点数
int visit[MAX];//每个节点是否访问过
int dist[MAX];//每个点到操作点的距离
}Graph;
int min(int x,int y){
if(x>y)
return y;
return x;
}
int dijklock=1;
//求最短路径
void Dijkstra(int option, Graph* g){
if(dijklock==1){
g->dist[option]=0;//只有第一次来需要初始化:初始操作数的dist为0
printf("dist[i]含义:从起点到i点的最短距离\n");
printf("已经初始化起点dist[0]=0\n");
dijklock=0;
}
int Min=16843009;
int min_num;
g->visit[option]=1;
printf(">>收录到%d点\n",option);
for(int i=0;i<g->vexnum;i++){
//给option连接到的所有节点都计算dist值
if(g->AdjMartix[option][i]!=16843009){//如果邻接矩阵=16843009表示不相连
printf("dist[%d]=%d,dist[%d](%d)+%d点到%d点距离=%d >>>",i,g->dist[i],option,g->dist[option],i,option,g->dist[option]+g->AdjMartix[option][i]);
g->dist[i]=min(g->dist[i],g->dist[option]+g->AdjMartix[option][i]);
//dist值为“无穷大/上次计算的起点到该点”距离和“起点到option点+option点到该点”距离中的较小值
printf("dist[%d]=%d\n",i,g->dist[i]);
}
//选出visit=0的节点中目前dist值最小的
if(g->dist[i]<Min&&g->visit[i]==0){
Min=g->dist[i];
min_num=i;
}
}
if(Min==16843009){
return;//到所有节点都被访问过的时候,min就是最大值了(其他值都被访问过了)
}
printf("Min=dist[%d]=%d\n",min_num,Min);
Dijkstra(min_num,g);
printf("递归结束\n");
}
//求最小生成树(对比dijkstra算法)
int* Prim(int option,Graph* g){
g->dist[option]=0;//dijkstra算法只有第一次需要初始化dist=0,但是prim需要每次递归dist都初始化为0
int Min=16843009;
int min_num;
g->visit[option]=1;
printf(">>收录到%d点\n",option);
for(int i=0;i<g->vexnum;i++){
//给option连接到的所有节点都更新dist值
if(g->AdjMartix[option][i]!=16843009){//如果邻接矩阵=16843009表示不相连
printf("dist[%d]=%d,起点到%d点再到%d点距离=%d >>>",i,g->dist[i],option,i,g->AdjMartix[option][i]);
g->dist[i]=min(g->AdjMartix[option][i],g->dist[i]);
//dist值为“无穷大/上次计算的起点到该点”距离和“起点到option点(0)+option点到该点”距离中的较小值
printf("dist[%d]=%d\n",i,g->dist[i]);
}
//选出visit=0的节点中目前dist值最小的
if(g->dist[i]<Min&&g->visit[i]==0){
Min=g->dist[i];
min_num=i;
}
}
if(Min==16843009){
printf("递归结束\n");
return;//到所有节点都被访问过的时候,min就是最大值了(其他值都被访问过了)
}
printf("最小dist是%d,连接到%d\n",g->dist[min_num],min_num);
Prim(min_num,g);
printf("递归结束\n");
return;
}
void OutputGraph(Graph* g){
printf("邻接矩阵输出-----\n");
printf(" ");
for(int i=0;i<g->vexnum;i++){
printf("%8s",g->vexs[i]);
}
printf("\n");
for(int i=0;i<g->vexnum;i++){
printf("%s ",g->vexs[i]);
for(int j=0;j<g->vexnum;j++){
if(g->AdjMartix[i][j]==16843009){
printf(" /");
continue;
}
printf("%8d",g->AdjMartix[i][j]);
}
printf("\n");
}
}
Graph* copy_graph(Graph* G){
Graph* New=(Graph*)malloc(sizeof(Graph));
memset(New,1,sizeof(Graph));
New->vexnum=G->vexnum;
for(int i=0;i<New->vexnum;i++){
New->vexs[i]=G->vexs[i];
}
}
Graph* create_sample_graph(void){
Graph* pG;
pG=(Graph*)malloc(sizeof(Graph));
memset(pG,1,sizeof(Graph));
pG->vexnum=7;
pG->vexs[0]="1";
pG->vexs[1]="2";
pG->vexs[2]="3";
pG->vexnum=7;
pG->vexs[0]="1";
pG->vexs[3]="4";
pG->vexs[4]="5";
pG->vexs[5]="6";
pG->vexs[6]="7";
//邻接矩阵 横行表示与该点的相邻点
pG->AdjMartix[get_position(pG,"1")][get_position(pG,"2")]=2;
pG->AdjMartix[get_position(pG,"2")][get_position(pG,"1")]=2;
pG->AdjMartix[get_position(pG,"2")][get_position(pG,"5")]=10;
pG->AdjMartix[get_position(pG,"5")][get_position(pG,"2")]=10;
pG->AdjMartix[get_position(pG,"2")][get_position(pG,"4")]=3;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"2")]=3;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"5")]=7;
pG->AdjMartix[get_position(pG,"5")][get_position(pG,"4")]=7;
pG->AdjMartix[get_position(pG,"5")][get_position(pG,"7")]=6;
pG->AdjMartix[get_position(pG,"7")][get_position(pG,"5")]=6;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"7")]=4;
pG->AdjMartix[get_position(pG,"7")][get_position(pG,"4")]=4;
pG->AdjMartix[get_position(pG,"7")][get_position(pG,"6")]=1;
pG->AdjMartix[get_position(pG,"6")][get_position(pG,"7")]=1;
pG->AdjMartix[get_position(pG,"6")][get_position(pG,"4")]=8;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"6")]=8;
pG->AdjMartix[get_position(pG,"3")][get_position(pG,"6")]=5;
pG->AdjMartix[get_position(pG,"6")][get_position(pG,"3")]=5;
pG->AdjMartix[get_position(pG,"3")][get_position(pG,"4")]=2;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"3")]=2;
pG->AdjMartix[get_position(pG,"1")][get_position(pG,"3")]=4;
pG->AdjMartix[get_position(pG,"3")][get_position(pG,"1")]=4;
pG->AdjMartix[get_position(pG,"1")][get_position(pG,"4")]=1;
pG->AdjMartix[get_position(pG,"4")][get_position(pG,"1")]=1;
return pG;
}
int get_position(Graph* g,char* c){
int i,j;
for(i=0;i<g->vexnum;i++){
//printf(".");
if(strcmp(g->vexs[i],c)==0){
//printf("输入有效[%d]\n",i,c);
return i;
}
}
//printf("未找到\n");
return -1;
}
void initvisit(Graph* g){
for(int i=0;i<g->vexnum;i++){
g->visit[i]=0;
g->dist[i]=16843009;
}
}
int main()
{
Graph* graph=create_sample_graph();
initvisit(graph);//初始化所有的visit节点
OutputGraph(graph);
Prim(0,graph);
//Dijkstra(0,graph);
OutputGraph(graph);
}