普里姆算法-最小生成树

感觉好久没更了。。。。。其实只是感觉,事情有点多,一时间有点懵,太原这几天一直在零零星星的下着雨,大一新生军训似乎要。。。。,早上也懒得起床了,生活过的有点糊涂。。。。东西好多啊,JavaScript,Opencv,还是要归于现实的,在9月把数据结构结束。

所以忍着头皮把普里姆明白一下。。。。,大晚上的,难受。。。明天早起啊!!!!

OK,正题,普里姆,最小生成树,注释里面有个人理解,先mark一下:

和前一篇的邻接矩阵的建立相同,主要是这个:可能不太好理解:

手残,画一下图啊

void  prime(Graph  map,char v)//普里姆算法//传入图,某个顶点
{
	int k;
	char  now_node,last_node;
	k=get_pos(map,v);//k是顶点下标,v是顶点值

	//edge辅助初始化////////////////////////////////
	for(int i=0;i<map->vexnum;i++)
	{
		if(i!=k)//除去开始的顶点
		{
			edge[i].node=v;//暂时都指向顶点v
			edge[i].side_weight=map->tyust[k][i];
		}

	}
	////////////////////////////////////////////////
	edge[k].side_weight=0;//访问过的标记为0

	for(int j=1;j<map->vexnum;j++)//上面已经标记一个顶点了,这里从1开始
	{
		k=search_min(map);//返回初始化那一层的最小权重的下标
		now_node=map->vexs[k];
		last_node=edge[k].node;
		printf("%c->%c\n",last_node,now_node);//打印边

		edge[k].side_weight=0;//访问过的权重标记为0

		for(int i=0;i<map->vexnum;i++)			//每一次都检查所有列
		{
			if(edge[i].side_weight>map->tyust[k][i])
			{
				//在已经选过的结点和目前结点所连的边线中找权重最小的
				//如果目前与结点有连线的权重小于之前的则进入重新赋为最小值
				edge[i].node=map->vexs[k];
				edge[i].side_weight=map->tyust[k][i];
			}
		}
	}
}

主要也就上面的啦,下面贴一下全部的:

/*普里姆算法*/
#include <iostream>
#include <malloc.h>
using namespace std;
#define  MAX_NUM  256//随便一个数,代表无穷大就ok
#define  edge_MAX 20//最大边20
#define   MAX     20
struct  tyust//辅助结构体
{
	int  side_weight;//边权重
	char node;//边结点
}edge[edge_MAX];

typedef  struct  graph
{
    int vexnum,arcnum;//节点个数,弧的个数
    int tyust[MAX][MAX];//使用二维数组定义一个矩阵
    char vexs[MAX];//存储节点数据
}*Graph;

/*
成功返回顶点位置,失败返回-1
*/
int get_pos(Graph map,char c)
{
	for(int i=0;i<map->vexnum;i++)
	{
		if(c==map->vexs[i])return i;
	}
	return -1;
}
/*
打印邻接矩阵
*/
void print(Graph map,int tyust[MAX][MAX])
{
	for(int i=0;i<map->vexnum;i++)
	{
		for(int j=0;j<map->vexnum;j++)
		{
		 printf("%-4d",tyust[i][j]);
		}printf("\n");
	}
}
/*
创建邻接矩阵图
*/
Graph creat_graph()
{
	int vex,arc,p1,p2;
	char in1,in2;
	int my_weight;
	Graph  pit;
	printf("请输入无向图节点数:\n");
	scanf("%d",&vex);
	printf("请输入无向图弧数:\n");
	scanf("%d",&arc);
	pit=(Graph)malloc(sizeof(graph));
	memset(pit,0,sizeof(graph));
	for(int i=0;i<vex;i++)
		for(int j=0;j<vex;j++)
		{
			pit->tyust[i][j]=MAX_NUM;
		}

	pit->vexnum=vex;
	pit->arcnum=arc;//初始化

	printf("输入vexs:\n");
	cin>>pit->vexs;

	//弧初始化
	for(int j=0;j<arc;j++)
	{
		printf("输入arc(%d)两个顶点和边的权重:\n",j);
		cin>>in1>>in2>>my_weight;

		p1=get_pos(pit,in1);
		p2=get_pos(pit,in2);
		if(p1==-1||p2==-1)
		{
			cout<<"获取位置失败!!"<<endl;
		}
		pit->tyust[p1][p2]=pit->tyust[p2][p1]=my_weight;
	}	
	print(pit,pit->tyust);
	return pit;
}

int search_min(Graph  map)//寻找最小权重,并返回
{
	int min=MAX_NUM;//先默认MAX_NUM为最小权重
	int temp=-1;//存放顶点下标
	for(int i=0;i<map->vexnum;i++)
	{
		if(min>edge[i].side_weight&&edge[i].side_weight!=0)//权重为0,表示已经遍历
		{
			min=edge[i].side_weight;
			temp=i;
		}

	}
	return temp;

}//返回-1,出错
void  prime(Graph  map,char v)//普里姆算法//传入图,某个顶点
{
	int k;
	char  now_node,last_node;
	k=get_pos(map,v);//下标
	//edge辅助初始化
	for(int i=0;i<map->vexnum;i++)
	{
		if(i!=k)//除去开始的顶点
		{
			edge[i].node=v;//暂时都指向顶点v
			edge[i].side_weight=map->tyust[k][i];
		}

	}
	////////////////////////////////////////////////
	edge[k].side_weight=0;//访问过的标记为0
	for(int j=1;j<map->vexnum;j++)
	{
		k=search_min(map);//返回初始化那一层的最小权重的下标
		now_node=map->vexs[k];
		last_node=edge[k].node;
		printf("%c->%c\n",last_node,now_node);//打印边
		edge[k].side_weight=0;//访问过的标记为0
		for(int i=0;i<map->vexnum;i++)			//每一次都检查所有列
		{
			if(edge[i].side_weight>map->tyust[k][i])
			{
				//在已经选过的结点和目前结点所连的边线中找权重最小的
				//如果目前与结点有连线的权重小于之前的则进入重新赋为最小值
				edge[i].node=map->vexs[k];
				edge[i].side_weight=map->tyust[k][i];
			}
		}
	}
}

void  main()
{
	Graph  map=creat_graph();
	prime(map,'A');
}

猜你喜欢

转载自blog.csdn.net/shuiyihang0981/article/details/82779830
今日推荐