(2)算法详细步骤如下表:
步骤
|
S集合中
|
U集合中
|
初始化
|
选入a,此时s={a}
此时最短路径有a->a=0
以a为中间点,从a开始找
|
U={b,c,d,e,f}
a->b=1
a->c=2
a->e=15
a->其他U中顶点为无穷
|
1
|
从U={b,c,d,e,f}中发现路径a->b=1最短
选入b,S={a,b}
此时最短路径有a->a=0,a->b=1
以b为中间点,从a->b=1这条最短路径开始找
|
U={c,d,e,f}
(a->b->d=7)<初始的无穷
改写a->b->d=无穷为当前的a->b->d=7
a-> b->其他U中顶点为无穷
|
2
|
从U={c,d,e,f}中发现路径a->c=2最短
选入c,S={a,b,c}
此时最短路径有
a->a=0,a->b=1,a->c=2
以b为中间点,从a->c=2这条最短路径开始找
|
U={d,e,f}
(a->c->d=5)<已有的7
改写为a->c->d=5
|
3
|
从U={d,e,f}中发现路径a->c->d=5最短
选入d,S={a,b,c,d}
此时最短路径有
a->a=0,a->b=1,a->c=2,a->c->d=5
以d为中间点,从a->c->d=5这条最短路径开始找
|
U={e,f}
(a->c->d->e=9)<步骤1中的15
改写为a->c->d->e=9
(a->c->d->f=6)<初始的无穷
改写为a->c->d->f=6
|
4
|
从U={e,f}中发现路径a->c->d->f=6最短
选入f,S={a,b,c,d,f}
此时最短路径有
a->a=0,a->b=1,a->c=2,a->c->d=5
a->c->d->f=6
以f为中间点,从a->c->d->f=6这条最短路径开始找
|
U={e}
(a->c->d->f->e=7)<步骤3中改写成的9
改写为a->c->d->f->e=7
|
5
|
从U={f}中发现路径a->c->d->f->e=7最短
选入f,S={a,b,c,d,f,e}
此时最短路径有
a->a=0,a->b=1,a->c=2,a->c->d=5
a->c->d->f=6,a->c->d->f->e=7
|
U集合已空,查找完毕。
|
/*迪杰斯特拉算法算法步骤: (1)初始时, S只包含源点。 (2)从U中选取一个距离v最小的顶点k加入S中(该选定的距离就是v到k的最短路径长度)。 (3)以k为新考虑的中间点, 修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短, 则修改顶点u的距离值, 修改后的距离值的顶点k的距离加上边上的权。 (4)重复步骤(2)和(3)直到所有顶点都包含在S中。 */ #include<iostream> #include<string.h> #include<stdlib.h> using namespace std; #define M 999 int cost[ 6 ][ 6 ] = { {M, M, 10, M, 30, 100}, {M, M, M, M, M, M }, {M, 5, M, 50, M, M }, {M, M, M, M, M, 10 }, {M, M, M, 20, M, 60 }, {M, M, M, M, M, M } }; //edge,严蔚敏书上所说的向量D typedef struct edge{ int adjvex; //边的一个顶点 int cost; //权值(从起点到当前顶点的权值) }edge; void main(){ int total = 0; //计数变量, 计算共选择节点多少个 int adjvex[ 6 ]; //保存依次被选中的节点 int i = 0; edge lowpathcost[ 6 ]; //初始值为矩阵的第一行。 char path[ 6 ][ 10 ] = {"0", "", "", "", "", ""}; //以0为初始节点开始计算最短路径 (路径) for(i = 1; i < 6; i++) { lowpathcost[ i ].cost = cost[ 0 ][ i ]; //初始化为M, 最短路径长度为矩阵的第一行权值 if(cost[ 0 ][ i ] != M) { lowpathcost[ i ].adjvex = 0; //有数据则adjvex置为0 //cout<<"初始存在路径的是"<<0<<"----"<<i<<endl; } } int min; //保存最小权值 int minvex; //保存最小权值边的另一顶点 int selected[ 6 ] = {0}; //次变量是作为控制已输出的节点不再参与的判断参数 //cout<<endl<<"开始选择顶点:"<<endl; for(int num = 1; num <= 5; num++) //要选择的次数, 共6个顶点, 除掉起点 { min = M; for(i = 1; i <= 5; i++) if(min > lowpathcost[ i ].cost && !selected[ i ]) { min = lowpathcost[ i ].cost; //第一次查找为10 即第一行中最小的值 minvex = i; //此时i=2 } adjvex[ ++total ] = minvex; //此时adjvex[1]为2, 存放依次选出的顶点 //adjvex[2]=1 if(min != M) { cout << "第 " << num << " 次被选择的顶点是:" << minvex << " . " <<"对应的边上的权值是 " << min << endl; } selected[ minvex ] = 1; //已参与的节点就置为1 for(i = 0; i < 6; i++)//这一个循环是算法步骤的第三步, D[j] + arcs[j][k] < D[k] if( !selected[ i ] && lowpathcost[ i ].cost > min + cost[ minvex ][ i ] && min + cost[ minvex ][ i ] < M )//3项都要满足 { lowpathcost[ i ].cost = min + cost[ minvex ][ i ]; lowpathcost[ i ].adjvex = minvex; } } for(i = 1; i <= 5; i++) cout<<" "<<lowpathcost[i].adjvex; int eadjvex, sadjvex; //当前顶点, 当前顶点的前驱顶点 char ep[ 2 ]; //将当前顶点变为字符串 for(i = 1; i <= total; i++) { eadjvex = adjvex[ i ]; sadjvex = lowpathcost[ eadjvex ].adjvex; ep[ 0 ] = '0' + eadjvex; ep[ 1 ] = '\0'; char tmp[ 10 ]; strcpy(tmp, path[ sadjvex ]); strcpy(path[ eadjvex ], strcat(tmp, ep)); // path[e]=sp+ep; cout << "0 到顶点 " << eadjvex << " 的最短路径经历的节点依次是:" << path[ eadjvex ] << " 长度是:" << lowpathcost[ eadjvex ].cost << endl; } }