(数据结构)编程实现最小生成树求解的Prim算法(邻接矩阵)

本文详细介绍了图论的基本概念,包括不同类型的图(有向图、无向图、带权图等)的创建与表示。通过具体的C++代码实现了最小生成树的Prim算法,展示了如何从指定顶点开始构建最小生成树的过程。文章提供了完整的源代码,包括头文件的定义、图的创建、打印以及Prim算法的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

头文件:‘1.h’

#include <stdio.h>
#include <iostream>
#include <malloc.h>
#include <string.h>
#define TRUE  1
#define FALSE 0
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW    -2
#define OK 1
typedef int Status;
using namespace std;

头文件:‘2.h’

#pragma once
#include  "1.h"
#define INFINITY 1000
#define MAX_VERTEX_NUM 20
typedef  char  VertexType;
typedef enum { DG, UDG, DN, UDN } GrapKind;
typedef struct
{
	VertexType vexs[MAX_VERTEX_NUM];
	int  arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
	int vexnum, arcnum;
	GrapKind kind;
}MGraph;
typedef struct
{
	VertexType adjvex;
	int lowcost;
}closede,closedes[MAX_VERTEX_NUM];

头文件:‘3.h’(函数的实现)

#include "2.h"
Status LovateVex(MGraph &G, VertexType v)
{
	int i;
	for (i = 0; i < G.vexnum; i++)
	{
		if (G.vexs[i] == v)
			return i;
	}

}
Status CreatDG(MGraph &G)
{
	VertexType v1, v2;
	cout << "输入顶点数和边数:";
	cin >> G.vexnum >> G.arcnum;
	int i, j;
	cout << "输入顶点:";
	for (i = 0; i < G.vexnum; ++i)
		cin >> G.vexs[i];
	for (i = 0; i < G.vexnum; ++i)
	{
		for (j = 0; j < G.vexnum; ++j)
		{
			G.arcs[i][j] = INFINITY;
		}
	}
	cout << "建立图,输入两个顶点:";
	int k;
	for (i = 0; i < G.arcnum; ++i)
	{
		cin >> v1 >> v2;
		j = LovateVex(G, v1);
		k = LovateVex(G, v2);
		G.arcs[j][k] = 1;


	}
	return OK;
}
Status CreatUDG(MGraph &G)
{
	VertexType v1, v2;
	cout << "输入顶点数和边数:";
	cin >> G.vexnum >> G.arcnum;
	int i, j;
	cout << "输入顶点:";
	for (i = 0; i < G.vexnum; ++i)
		cin >> G.vexs[i];
	for (i = 0; i < G.vexnum; ++i)
	{
		for (j = 0; j < G.vexnum; ++j)
		{
			G.arcs[i][j] = INFINITY;
		}
	}
	cout << "建立图,输入两个顶点:";
	int k;
	for (i = 0; i < G.arcnum; ++i)
	{
		cin >> v1 >> v2;
		j = LovateVex(G, v1);
		k = LovateVex(G, v2);
		G.arcs[j][k] = 1;
		G.arcs[k][j] = 1;


	}
	return OK;
}
Status CreatDN(MGraph &G)
{
	VertexType v1, v2;
	cout << "输入顶点数和边数:";
	cin >> G.vexnum >> G.arcnum;
	int i, j;
	cout << "输入顶点:";
	for (i = 0; i < G.vexnum; ++i)
		cin >> G.vexs[i];
	for (i = 0; i < G.vexnum; ++i)
	{
		for (j = 0; j < G.vexnum; ++j)
		{
			G.arcs[i][j] = INFINITY;
		}
	}
	cout << "建立图,输入两个顶点和权值:";
	int k, w;
	for (i = 0; i < G.arcnum; ++i)
	{
		cin >> v1 >> v2 >> w;
		j = LovateVex(G, v1);
		k = LovateVex(G, v2);
		G.arcs[j][k] = w;


	}
	return OK;
}
Status CreatUDN(MGraph &G)
{
	VertexType v1, v2;
	cout << "输入顶点数和边数:";
	cin >> G.vexnum >> G.arcnum;
	int i, j;
	cout << "输入顶点:";
	for (i = 0; i < G.vexnum; ++i)
		cin >> G.vexs[i];
	for (i = 0; i < G.vexnum; ++i)
	{
		for (j = 0; j < G.vexnum; ++j)
		{
			G.arcs[i][j] = INFINITY;
		}
	}
	cout << "建立图,输入两个顶点和权值:";
	int k, w;
	for (i = 0; i < G.arcnum; ++i)
	{
		cin >> v1 >> v2 >> w;
		j = LovateVex(G, v1);
		k = LovateVex(G, v2);
		G.arcs[j][k] = w;
		G.arcs[k][j] = w;


	}
	return OK;
}
Status GreatGraph(MGraph &G)
{
	cout << "输入图类型:" << "0-DG,1-UDG,2-DN,3-UDN" << endl;
	int kind;
	cin >> kind;
	G.kind = (GrapKind)kind;
	switch (G.kind)
	{
	case 0:return CreatDG(G); break;
	case 1:return  CreatUDG(G); break;
	case 2:return CreatDN(G); break;
	case 3:return CreatUDN(G); break;


	}

}
void PrintMGraph(MGraph G)
{
	int i, j;
	cout << endl << "图的顶点数和边数:";
	cout << endl << G.vexnum << " " << G.arcnum;
	cout << endl << "图的顶点信息:" << endl;
	for (i = 0; i < G.vexnum; i++)
		cout << " " << G.vexs[i];
	cout << endl << "图的邻接矩阵:" << endl;
	if (G.kind == 0 || G.kind == 1)
	{
		for (i = 0; i < G.vexnum; ++i)
		{
			for (j = 0; j < G.vexnum; ++j)
			{
				if (G.arcs[i][j] == INFINITY)
					cout << " " << "0";
				else
					cout << " " << G.arcs[i][j];
			}
			cout << endl;
		}
	}
	else
	{
		for (i = 0; i < G.vexnum; ++i)
		{
			for (j = 0; j < G.vexnum; ++j)
			{
				if (G.arcs[i][j] == INFINITY)
					cout << " " << "∞";
				else
					cout << " " << G.arcs[i][j];
			}
			cout << endl;
		}
	}

}
int mininum(closedes  closedge,MGraph G)
{
	int mini, j;
	for (j = 0; j < G.vexnum; j++)
	{

		if (closedge[j].lowcost != 0)
			break;
	}
	mini = j;
     

	for (j=j+1; j < G.vexnum; j++)
	{
		if ((closedge[j].lowcost < closedge[mini].lowcost)&&closedge[j].lowcost!=0)
		{
			mini = j;
		}
	}
	return mini;
}
void MiniSpanTree_PRIM(MGraph G, VertexType u)//从u为起点的最小生成树
{
	int k,i;
	closedes closedge;
	k = LovateVex(G, u);
	int j;
	for (j = 0; j < G.vexnum; j++)//初始化closedge
	{
		if (j != k)
		{
			closedge[j].adjvex = u;
			closedge[j].lowcost = G.arcs[k][j];
		}

			
	}

	closedge[k].lowcost = 0;
	for (j = 0; j < G.vexnum; j++)//找剩下点中路径最短的
	{
		k = mininum(closedge, G);
		cout << closedge[k].adjvex<<"->"<< G.vexs[k]<<  endl;

		closedge[k].lowcost = 0;//把k点并入U集合
		for (i = 0; i < G.vexnum; i++)
		{
			if (closedge[i].lowcost > G.arcs[k][i])
			{
				closedge[i].lowcost = G.arcs[k][i];
				closedge[i].adjvex = G.vexs[k];


			}

		}
	}

}

主函数:

#include "3.h"
int main()
{
	MGraph G;
	GreatGraph(G);
	PrintMGraph(G);
	VertexType u;
	cout << "请输入最小生成树顶点:";
	cin >> u;
	MiniSpanTree_PRIM(G, u);
	system("pause");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值