这是我参与11月更文挑战的第11天,活动详情查看:2021最后一次更文挑战
1. Floyd算法
Dijkstra算法是主要解决的是单源最短路径 而Floyd算法可以解决的是多源最短路径 他是解决任意两点间的最短路径算法(也可以解决对于权值为负的问题)--而Floyd算法是一个经典的动态规划问题 根据一个例子去了解什么是Floyd算法
Floyd算法大概的思想是这样的:把各个顶点之间的距离以二维表的形式表示出来 若vi能到vj则填写其权值 若没有可以无穷大表示即可 当选择经过一个顶点的时候就更新这张表的值(因为可能加入这个顶点 以这个顶点为辅助 vi到vj的值可以变小)若比原来值小则就更新二维数组
接下来一起来看下他算法实现吧:
void Floyd(Graph G){
int A[G.vexnum][G.vexnum];
for(int i=0;i<G.vexnum;i++){
for(int j=-;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]){ //判断加入这个顶点后vi到vj的路径是否可以变小
A[i][j] = A[i][k] + A[k][j] ;
}
}
}
}
}
性能分析: 时间复杂度为 O(|V|3)
2. 拓扑排序
今天想分享一个拓扑排序 拓扑排序是针对有向无环图而言的,简单来说就是Vi是Vj的前驱,要想进行活动Vj则必须完成Vi才能进行Vj 就主要是有一个顺序在里面 例如下面这个图
-
选择一个入度为0的顶点并输出
-
从网中删除该顶点和所有以它为起点的出边 再不断重复这两个步骤 故序列是这样 1,2,4,3,5
则其代码如下:
void topoSort(Graph G){
InitStack(S); //初始化一个栈
for(int i=0;i<G.vexnum;i++) {
if(indegree[i]==0){
Push(S,i)
}
}
int count = 0;
while(!isEmpty(S)){
Pop(S,i);
p[count++]=i;
for(p=G.vertics[i].fristarc;p;p->nextarc){
v=p->adjvex;
if(!(--indegree[v])){
Push(S,v);
}
}
}
if(count<G.vexnum) {
return false; //失败,有向图中有回路
} else {
return true; //成功
}
}