最小生成树
Prim算法
图解
一些说明:
min_weight数组表示该集合到达剩余顶点的最小值
adjvex表示这个最小权值是由哪个顶点引入
每次选取最小的权值顶点加入后,需要更新min_weight的数值,选取值变为0,全部都为0时表示树已经生成
代码
void MST_Prim(Grap G)
{
//初始化部分
int min_weight[G.vexnum];
int adjvex[G.vexnum];
for (int i=0;i<G.vexnum;i++)
{
min_weight[i]=G.Edge[0][i];//赋值第0个顶点到其他边的权值
adjvex[i]=0;
}
int min_arc;//弄两个缓存下变量
int min_vex;
for(int i=1;i<G.vexnum;i++)//少了一个顶点,故从这里开始
{
//挑选出最小权值的顶点
min_arc=MAX;
for(int j=1;j<G.vexnum;j++)
if(min_weight[j]!=0 && min_weight[j]<min_arc)
{
min_arc=min_weight[j];
min_vex=j;
}
//重新分配该集合权重,并去掉该顶点,以及记录最小权值是从哪条边发出
min_weight[min_vex]=0;
for(int j=0;j<G.vexnum;j++)
{
if(min_weight[j]!=0 && G.Edge[min_arc][j]<min_weight[j])
{
min_weight[j]=G.Edge[min_arc][j];
adjvex[j]=min_arc;
}
}
}
}
Kruskal
图解
一些说明:
要判断图中有没有回路,只需要判断两个顶点在并查集中有没有共同根,有的话加入就变成有回路了。
代码
type struct Edge//边信息
{
int a,b;
int weight;
}
void MST_Kruskal(Graph G, Edge* edges, int* parent)
{
heap_sort(edges);//对所有边进行排序
Initial(parent);//初始化数组为-1
for(int i=0;i<G.arcnum;i++)
{
//每次加入新边时候,查找该边的两个顶点是否有公共根,没有就加入新树
int a_root=Find(parent,edges[i].a);
int b_root=Find(parent,edges[i].b);
if(a_root!=b_root)
Union(parent,a_root,b_root);
}
}
最短路径
Dijkstra算法(迪杰斯特拉)
步骤描述
图解
每次挑选出权值最小的没有用过的顶点加入,然后遍历顶点的边,看看通过该顶点能否使得对应路径变短
查找路径
代码
void Dijkstra(Graph G,int V)
{
//初始化开始的三个数组
int s[G.vexnum];
int path[G.vexnum];
int dist[G.vexnum];
for(int i=0;i<G.vexnum;i++)
{
dist[i]=G.edge[v][i];
s[i]=0;
if(G.edge[v][i]<MAX)
path[i]=v;
else
path[i]=-1;
}
//一开始引用的顶点要初始化
s[v]=1;
path[v]=-1;
//正文
for(i=0;i<G.vexnum;i++)
{
int min=MAX;
int u;
//挑选最小而且没用过的顶点
for(int j=0;j<G.vexnum;j++)
if(s[j]==0 && dist[j]<min)
{
min=dist[j];
u=j;
}
s[u]=1;
//遍历该顶点各边,小于就更新
for(int j=0;j<G.vexnum;j++)
if(s[j]==0 && dist[u]+G.Edge[u][j]<dist[j])
{
dist[j]=dist[u]+G.Edge[u][i];
path[j]=u;
}
}
}
Floyd算法(弗洛伊德)
步骤
图解
代码
void Floyd(Graph G)
{
//初始化
int A[G.vexnum][G.vexnum];
for(int i=0;i<G.vexnum;i++)
for(int j=0;j<G.vexnum;j++)
A[i][j]=G.Edge[i][j];
//依次加入顶点,然后依次遍历整个矩阵检查
for(int k=0;k<G.vexnum;k++)
for(int i=0;i<G.vexnum;i++)
for(int j=0;j<G.vexnum;j++)
if(A[i][j]>A[i][k]+A[k][j])
A[i][j]=A[i][k]+A[k][j];
}
拓扑排序
应用
在课程排序中,由课程关系得到一个AOV网络,然后根据排课需要输入的就是拓扑排序了。
算法描述
算法图解
关键路径
经典应用
觉得好记得点个赞|ू・ω・` )