图的邻接矩阵存储看这里
使用的图为:
最小生成树Prim算法
- 首先标记第一个点已经确定,然后计算出第一个点到其余各个未确定点的权值,并修改邻接点为第一个点
- 之后每一步都找到上一步更新后的权值中最小的那个点,确定该点并计算出该点到其余各个未确定点的权值,若比原来的权值小则更新权值与邻接点,否则保持原来的权值和邻接点
- 每一步确定一个点,直到所有的点都被确定则结束
需要定义新的结构:
template<typename VertexType, typename VRType>
struct ClosEdgeType
{
VertexType adjvex;
VRType lowcost;
};
template<typename VertexType, typename VRType>
using ClosEdge = ClosEdgeType<VertexType, VRType>[MAX_VERTEX_NUM];
具体实现:
template<typename VertexType, typename VRType>
int minimum(ClosEdge<VertexType, VRType> closedge, int num)//取最小权值的下标
{
int low = INFINITY;
int lowpos = 0;
for (int i = 0; i < num; i++)
{
if (closedge[i].lowcost > 0 && closedge[i].lowcost < low)
{
low = closedge[i].lowcost;
lowpos = i;
}
}
return lowpos;
}
template<typename VertexType, typename VRType, typename InfoType>
void miniSpanTree_PRIM(MGraph<VertexType, VRType, InfoType>MG, VertexType u)//最小生成树 Prim算法
{
cout << "最小生成树:" << endl;
ClosEdge<VertexType, VRType> closedge;
int k = locateVex(MG, u);//找到u在数组中的下标
closedge[k].lowcost = 0;//表示已经确定u
for (int i = 0; i < MG.vexnum; i++)//初始化u到其余点的权重
{
if (i != k)
{
closedge[i].adjvex = u;
closedge[i].lowcost = MG.arcs[k][i].adj;
}
}
for (int i = 0; i < MG.vexnum - 1; i++)
{
k = minimum(closedge, MG.vexnum);//找到上一步确定的点到其余点权值最小的点
closedge[k].lowcost = 0;//确定该点
cout << "(" << closedge[k].adjvex << ", " << MG.vexs[k] << ")" << endl;//输出路径
for (int j = 0; j < MG.vexnum; j++)//遍历k点到其余未确定顶点的权值
{
if (closedge[j].lowcost > 0 && MG.arcs[k][j].adj < closedge[j].lowcost)
{//如果k->j的权值小于之前求得的到j的最小权值
closedge[j].adjvex = MG.vexs[k];
closedge[j].lowcost = MG.arcs[k][j].adj;
}
}
}
}
最短路径Dijkstra算法
- 首先确定第一个点到其余各个顶点的路径,并修改邻接点,标记第一个点已经找到最短路径
- 每一步都寻找从第一个点出发到各个未确定点当中路径最短的点,确定该顶点
- 计算第一个点经上一步确定的点到其余各个未确定点的距离,再与原本第一个点到其余各个未确定点的距离比较,取小者,并设置相应路径长度和邻接点
- 每次确定一个点,直到确定所有顶点
需要定义新的结构:
using PathMatrix = int[MAX_VERTEX_NUM];
具体实现:
template<typename VertexType,typename VRType,typename InfoType, typename ShortPathTable>
void shortestPath_DIJ(MGraph<VertexType, VRType, InfoType>MG, int v0, PathMatrix& P, ShortPathTable& D)//最短路径 Dijkstra算法
{//P[i] v0到vi要经过的、vi直接前驱的点 D[i] v0到vi当前找到的最短路径长度
bool finals[MAX_VERTEX_NUM] = { false };//标识已经找到从v0出发到下标对应的点的最短路径
for (int i = 0; i < MG.vexnum; i++)//初始化
{
finals[i] = false;//未找到到i的最短路径
D[i] = MG.arcs[v0][i].adj;//v0到i的最短路径
if (D[i] < INFINITY)
P[i] = v0;//表示v0可以到i
else
P[i] = -1;//表示目前没有点可以到i
}
D[v0] = 0;//v0到v0的最短路径
finals[v0] = true;//已经找到v0到v0的最短路径
for (int i = 0; i < MG.vexnum - 1; i++)
{
VRType min = INFINITY;
int v;
for (int j = 0; j < MG.vexnum; j++)//遍历所有节点,寻找所有v0到j中距离最短的那个j
{
if (!finals[j])
{
if (D[j] < min)
{
v = j;//v表示当前最短的v0到j的路径
min = D[j];
}
}
}//找到路径最短的v0到v
finals[v] = true;
for (int i = 0; i < MG.vexnum; i++)
{
if (!finals[i] && (MG.arcs[v][i].adj + min < D[i]) && (MG.arcs[v][i].adj < INFINITY))//比较v0到v再到i的路径和原先路径的长度
{
D[i] = MG.arcs[v][i].adj + min;
P[i] = v;
}
}
}
}
template<typename VertexType, typename VRType, typename InfoType, typename ShortPathTable>
void printShortestPath_DIJ(MGraph<VertexType, VRType, InfoType> MG, PathMatrix P, ShortPathTable D, int v, int w)
{//打印最短路径
cout << MG.vexs[v] << "到" << MG.vexs[w] << "最短路径:" << endl;
SqStack<int> S;
initSqStsck(S);
int t = w;
push(S, t);
while (P[t] != -1)
{
t = P[t];
push(S, t);
}
while (!isEmpty(S))
{
pop(S, t);
cout << MG.vexs[t] << "-->";
}
cout << "\b\b\b \t路径长度:";
D[w] == INFINITY ? cout << "∞" : cout << D[w];
cout << endl;
}
最短路径Floyd算法
- 首先计算各个顶点之间的距离,修改邻接表
- 循环求出各个顶点分别经所有顶点到其余各个顶点的路径与原有路径比较,取小者,设置邻接点
具体实现:
template<typename VertexType, typename VRType, typename InfoType>
void shortestPath_FLOYD(MGraph<VertexType, VRType, InfoType>MG, int (*P)[MAX_VERTEX_NUM], int (*D)[MAX_VERTEX_NUM])
{//最短路径 Floyd算法
for (int i = 0; i < MG.vexnum; i++)//初始化每个顶点间的距离
for (int j = 0; j < MG.vexnum; j++)
{
D[i][j] = MG.arcs[i][j].adj;
if (D[i][j] != INFINITY)
P[i][j] = i;//i->j经过i
}
for (int k = 0; k < MG.vexnum; k++)
for (int i = 0; i < MG.vexnum; i++)
for (int j = 0; j < MG.vexnum; j++)
{
if ((D[i][j] > D[i][k] + D[k][j]) && D[i][k] < INFINITY && D[k][j] < INFINITY)//i->k->j的距离比之前求得的i->j的距离小
{//替换最短路径
D[i][j] = D[i][k] + D[k][j];
P[i][j] = k;
}
}
}