图的最短路径Prim算法
我们将用临接矩阵来表示该图(具体代码将在思路构思下面显示)。
-
创建mst数组
mst[0]、 mst[1]、 mst[2]、 mst[3]、 mst[4]、 mst[5]。
mst[0]代表A、mst[1]代表B、mst[2]代表C、mst[3]代表D、mst[4]代表E、mst[5]代表F、
例如:
mst[0] = 1,的意思是A顶点与B顶点的边相连接,
mst[1] = 2,的意思是B顶点与C顶点的边相连接。(以此类推)
0 1 2 3 4 5
A B C D E F -
创建lowcast数组
lowcast[0]、lowcast[1]、lowcast[2]、lowcast[3]、lowcast[4]、lowcast[5]。
例如:
lowcast[0]=5,的意思是mst[0](即A与其连接顶点的边)的值为 5;
lowcast[1]=9,的意思是mst[1](即B与其连接顶点的边)的值为 9;(以此类推) -
我们将开始从A点开始进行寻找(*代表无穷大代表两个节点之间没有连接线路)
初始化
A----->C 权值为1:
从A节点出发寻找每个节点与A节点的距离,随后寻找lowcast数组中最小的一个即lowcast[2]=1,随后将mst[2]的值赋值为-1代表该节点已经被使用,在随后的比较中将不再对mst[2]进行比较
随后我们将查找各边以A、C顶点相连接中最小的边,由于C顶点的加入lowcast数组和mst数组也要发生改变。(将未标记mst[i]=-1的顶点与A,C顶点连接的边的最小值加入到lowcast和mst数组中)
注意:红色代表已经访问的节点后续不参与比较,紫色代表本轮查询到的最小值,白色代表还未添加的节点
将C顶点标记为已访问,C----->F权值为4
将F顶点标记为已访问,F----->D权值为2
将B顶点标记为已访问,C----->B权值为5
将E顶点标记为已访问,B----->E权值为3
最终绿色的线代表最短的路径
//头文件
//依据邻接矩阵来实现,所以包含了邻接矩阵的创建删除等方法
#pragma once
#include<stdio.h>
#include<malloc.h>
#include<assert.h>
#define Default_Vertex_Size 10
#define T char
#define E int
#define MAX_COST 0x7FFFFFFF
typedef struct GraphMtx
{
int MaxVertices;
int NumVertices;
int NumEdges;
T *VerticesList;
int **Edge;
}GraphMtx;
void InitGraph(GraphMtx *g);
int GetVertexPos(GraphMtx *g, T v);
void ShowGraph(GraphMtx *g);
void InsertVertex(GraphMtx *g, T v);
void InsertEdge(GraphMtx *g, T v1, T v2, E cost);
void RemoveVertex(GraphMtx *g, T v);
void RemoveEdge(GraphMtx *g, T v1, T v2);
void DestroyGraph(GraphMtx *g);
int GetFirstNeighbor(GraphMtx *g, T v);
int GetNextNeighbor(GraphMtx *g, T v, T w);
E GetWeight(GraphMtx *g, int v1, int v2);
void MinSpanTree_Prim(GraphMtx *g, T vertex);
//邻接矩阵的方法实现,以及Prim算法的实现
#include"GraphMtx.h"
//初始化
void InitGraph(GraphMtx *g)
{
g->MaxVertices = Default_Vertex_Size;
g->NumVertices = g->NumEdges = 0;
g->VerticesList = (T*)malloc(sizeof(T)*(g->MaxVertices));
assert(g->VerticesList != NULL);
g->Edge = (int**)malloc(sizeof(int*) * g->MaxVertices);
assert(g->Edge != NULL);
for(int i=0; i<g->MaxVertices; ++i)
{
g->Edge[i] = (int*)malloc